basic imagemodel and editor

This commit is contained in:
Chris Cochrun 2022-04-08 17:24:18 -05:00
parent 09b6370153
commit 0cee5db60d
11 changed files with 432 additions and 102 deletions

View file

@ -8,6 +8,9 @@ import "./" as Presenter
Item {
id: root
property string type: "image"
property var image
GridLayout {
id: mainLayout
anchors.fill: parent
@ -83,15 +86,15 @@ Item {
border.color: Kirigami.Theme.activeBackgroundColor
border.width: 2
}
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
closePolicy: Controls.Popup.CloseOnEscape | Controls.Popup.CloseOnPressOutsideParent
ColumnLayout {
anchors.fill: parent
Controls.ToolButton {
Layout.fillHeight: true
Layout.fillWidth: true
text: "Video"
icon.name: "emblem-videos-symbolic"
onClicked: videoFileDialog.open() & backgroundType.close()
text: "Image"
icon.name: "emblem-images-symbolic"
onClicked: imageFileDialog.open() & backgroundType.close()
}
Controls.ToolButton {
Layout.fillWidth: true
@ -121,11 +124,11 @@ Item {
ColumnLayout {
Controls.SplitView.fillHeight: true
Controls.SplitView.preferredWidth: 500
Controls.SplitView.minimumWidth: 500
Controls.SplitView.preferredWidth: 300
Controls.SplitView.minimumWidth: 100
Controls.TextField {
id: songTitleField
id: imageTitleField
Layout.preferredWidth: 300
Layout.fillWidth: true
@ -133,98 +136,46 @@ Item {
Layout.rightMargin: 20
placeholderText: "Song Title..."
text: songTitle
text: "idk"
padding: 10
onEditingFinished: updateTitle(text);
}
Controls.TextField {
id: songVorderField
Layout.preferredWidth: 300
Layout.fillWidth: true
Layout.leftMargin: 20
Layout.rightMargin: 20
placeholderText: "verse order..."
text: songVorder
padding: 10
onEditingFinished: updateVerseOrder(text);
/* onEditingFinished: updateTitle(text); */
}
Controls.ScrollView {
id: songLyricsField
Layout.preferredHeight: 3000
Layout.fillWidth: true
Item {
id: empty
Layout.fillHeight: true
Layout.leftMargin: 20
rightPadding: 20
Controls.TextArea {
id: lyricsEditor
width: parent.width
placeholderText: "Put lyrics here..."
persistentSelection: true
text: songLyrics
textFormat: TextEdit.MarkdownText
padding: 10
onEditingFinished: {
updateLyrics(text);
editorTimer.running = false;
}
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
onEditingFinished: updateAuthor(text)
}
}
ColumnLayout {
Controls.SplitView.fillHeight: true
Controls.SplitView.preferredWidth: 700
Controls.SplitView.minimumWidth: 300
spacing: 5
Rectangle {
id: slideBar
color: Kirigami.Theme.highlightColor
Layout.preferredWidth: 500
Layout.preferredHeight: songTitleField.height
Layout.rightMargin: 20
Layout.leftMargin: 20
Item {
id: topEmpty
Layout.fillHeight: true
}
Presenter.SlideEditor {
id: slideEditor
Layout.preferredWidth: 500
Layout.fillWidth: true
Layout.preferredHeight: slideEditor.width / 16 * 9
Layout.bottomMargin: 30
Layout.rightMargin: 20
Layout.leftMargin: 20
Image {
id: imagePreview
Layout.preferredWidth: 600
Layout.preferredHeight: Layout.preferredWidth / 16 * 9
Layout.alignment: Qt.AlignCenter
fillMode: Image.PreserveAspectFit
source: "file://" + image.toString()
}
Item {
id: botEmpty
Layout.fillHeight: true
}
}
}
}
function changeImage(image) {
root.image = image;
print(image.toString());
}
Timer {
id: editorTimer
interval: 1000
repeat: true
running: false
onTriggered: updateLyrics(lyricsEditor.text)
}
}

View file

@ -485,12 +485,40 @@ Item {
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
color: Kirigami.Theme.backgroundColor
opacity: 1.0
Controls.Label {
id: imageLabel
anchors.centerIn: parent
text: "Images"
}
Controls.Label {
id: imageCount
anchors {left: imageLabel.right
verticalCenter: imageLabel.verticalCenter
leftMargin: 15}
text: imagesqlmodel.rowCount()
font.pixelSize: 15
color: Kirigami.Theme.disabledTextColor
}
Kirigami.Icon {
id: imageDrawerArrow
anchors {right: parent.right
verticalCenter: imageCount.verticalCenter
rightMargin: 10}
source: "arrow-down"
rotation: selectedLibrary == "images" ? 0 : 180
Behavior on rotation {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
@ -508,6 +536,9 @@ Item {
Layout.preferredHeight: parent.height - 200
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
model: imagesqlmodel
delegate: imageDelegate
clip: true
state: "deselected"
states: [
@ -534,6 +565,118 @@ Item {
duration: 300
}
}
Component {
id: imageDelegate
Item{
implicitWidth: ListView.view.width
height: selectedLibrary == "images" ? 50 : 0
Kirigami.BasicListItem {
id: imageListItem
property bool rightMenu: false
implicitWidth: imageLibraryList.width
height: selectedLibrary == "images" ? 50 : 0
clip: true
label: title
/* subtitle: author */
supportsMouseEvents: false
backgroundColor: {
if (parent.ListView.isCurrentItem) {
Kirigami.Theme.highlightColor;
} else if (imageDragHandler.containsMouse){
Kirigami.Theme.highlightColor;
} else {
Kirigami.Theme.backgroundColor;
}
}
textColor: {
if (parent.ListView.isCurrentItem || imageDragHandler.containsMouse)
activeTextColor;
else
Kirigami.Theme.textColor;
}
Behavior on height {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
Drag.active: imageDragHandler.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
Drag.keys: [ "library" ]
states: State {
name: "dragged"
when: imageListItem.Drag.active
PropertyChanges {
target: imageListItem
x: x
y: y
width: width
height: height
}
ParentChange {
target: imageListItem
parent: rootApp.overlay
}
}
}
MouseArea {
id: imageDragHandler
anchors.fill: parent
hoverEnabled: true
drag {
target: imageListItem
onActiveChanged: {
if (imageDragHandler.drag.active) {
dragItemTitle = title;
dragItemType = "image";
dragItemText = "";
dragItemBackgroundType = "image";
dragItemBackground = filePath;
} else {
imageListItem.Drag.drop()
}
}
filterChildren: true
threshold: 10
}
MouseArea {
id: imageClickHandler
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if(mouse.button == Qt.RightButton)
rightClickImageMenu.popup()
else{
imageLibraryList.currentIndex = index
const image = imagesqlmodel.getImage(imageLibraryList.currentIndex);
if (!editMode)
editMode = true;
editType = "image";
editSwitch(image);
}
}
}
}
Controls.Menu {
id: rightClickImageMenu
x: imageClickHandler.mouseX
y: imageClickHandler.mouseY + 10
Kirigami.Action {
text: "delete"
onTriggered: imagesqlmodel.deleteImage(index)
}
}
}
}
}
Rectangle {

View file

@ -66,17 +66,24 @@ Controls.Page {
id: presentation
anchors.fill: parent
}
Presenter.SongEditor {
id: songEditor
visible: false
anchors.fill: parent
}
Presenter.VideoEditor {
id: videoEditor
visible: false
anchors.fill: parent
}
Presenter.ImageEditor {
id: imageEditor
visible: false
anchors.fill: parent
}
}
Presenter.Library {
@ -102,6 +109,10 @@ Controls.Page {
id: videosqlmodel
}
ImageSqlModel {
id: imagesqlmodel
}
ServiceItemModel {
id: serviceItemModel
}
@ -141,19 +152,24 @@ Controls.Page {
presentation.visible = false;
videoEditor.visible = false;
videoEditor.stop();
imageEditor.visible = false;
songEditor.visible = true;
songEditor.changeSong(item);
break;
case "video" :
presentation.visible = false;
songEditor.visible = false;
imageEditor.visible = false;
videoEditor.visible = true;
videoEditor.changeVideo(item);
break;
case "image" :
mainPageArea.pop(Controls.StackView.Immediate);
mainPageArea.push(imageEditorComp, Controls.StackView.Immediate);
presentation.visible = false;
videoEditor.visible = false;
videoEditor.stop();
songEditor.visible = false;
imageEditor.visible = true;
imageEditor.changeImage(item);
break;
default:
videoEditor.visible = false;