lumina-qml/src/qml/presenter/LibraryItem.qml

438 lines
15 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.15 as Controls
import QtQuick.Layouts 1.15
import Qt.labs.platform 1.1 as Labs
import QtQuick.Pdf 5.15
import QtQml.Models 2.15
import org.kde.kirigami 2.13 as Kirigami
import "./" as Presenter
import org.presenter 1.0
ColumnLayout {
id: root
property var proxyModel
property var innerModel
property string libraryType
property string headerLabel
property string itemLabel
property string itemSubtitle
property string itemIcon
property string count
property var newItemFunction
property var deleteItemFunction
property ListView libraryList: libraryList
states: [
State {
name: "deselected"
when: (selectedLibrary !== libraryType)
PropertyChanges {
target: root
Layout.preferredHeight: Kirigami.Units.gridUnit * 1.5
}
},
State {
name: "selected"
when: (selectedLibrary == libraryType)
PropertyChanges { target: root }
}
]
transitions: Transition {
to: "*"
NumberAnimation {
target: root
properties: "preferredHeight"
easing.type: Easing.OutCubic
duration: 300
}
}
Rectangle {
id: libraryPanel
Layout.preferredHeight: 40
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
z: 2
color: Kirigami.Theme.backgroundColor
Controls.Label {
id: libraryLabel
/* anchors.centerIn: parent */
anchors.left: parent.left
anchors.leftMargin: 15
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideLeft
text: headerLabel
color: libraryMouseArea.containsMouse ? Kirigami.Theme.focusColor : Kirigami.Theme.textColor
}
Controls.Label {
id: countLabel
anchors {left: libraryLabel.right
verticalCenter: libraryLabel.verticalCenter
leftMargin: 15}
text: count
font.pointSize: 9
color: libraryMouseArea.containsMouse ? Kirigami.Theme.focusColor : Kirigami.Theme.textColor
}
Kirigami.Icon {
id: drawerArrow
anchors {right: parent.right
verticalCenter: libraryLabel.verticalCenter
rightMargin: 10}
source: "arrow-down"
rotation: selectedLibrary == libraryType ? 0 : 180
color: libraryMouseArea.containsMouse ? Kirigami.Theme.focusColor : Kirigami.Theme.textColor
Behavior on rotation {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
}
MouseArea {
id: libraryMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (selectedLibrary == libraryType)
selectedLibrary = ""
else
selectedLibrary = libraryType
/* console.log(selectedLibrary) */
}
}
}
Rectangle {
id: libraryHeader
z: 2
Layout.preferredHeight: 40
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
/* width: parent.width */
color: Kirigami.Theme.backgroundColor
opacity: 1
state: "selected"
states: [
State {
name: "deselected"
when: (selectedLibrary !== libraryType)
PropertyChanges {
target: libraryHeader
Layout.preferredHeight: 0
}
},
State {
name: "selected"
when: (selectedLibrary == libraryType)
PropertyChanges { target: libraryHeader }
}
]
Kirigami.ActionToolBar {
height: parent.height
width: parent.width
display: Controls.Button.IconOnly
visible: selectedLibrary == libraryType
rightPadding: 5
actions: [
Kirigami.Action {
icon.name: "document-new"
text: "New " + libraryType
tooltip: "Add a new " + libraryType
onTriggered: newItemFunction()
},
Kirigami.Action {
id: searchField
displayComponent: Kirigami.SearchField {
id: searchField
height: parent.height
width: parent.width - 40
onAccepted: {
innerModel.search(text);
}
background: Presenter.TextBackground {
control: searchField
}
}
}
]
Behavior on height {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
}
}
ListView {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
id: libraryList
model: innerModel
clip: true
ItemSelectionModel {
id: selectionModel
model: innerModel
onSelectionChanged: {
/* showPassiveNotification("deslected: " + deselected); */
/* showPassiveNotification("selected: " + selected); */
/* console.log(selected); */
}
}
delegate: libraryDelegate
state: "selected"
states: [
State {
name: "deselected"
when: (selectedLibrary !== libraryType)
PropertyChanges {
target: libraryList
Layout.preferredHeight: 0
}
},
State {
name: "selected"
when: (selectedLibrary == libraryType)
PropertyChanges { target: libraryList }
}
]
transitions: Transition {
to: "*"
NumberAnimation {
target: libraryList
properties: "preferredHeight"
easing.type: Easing.OutCubic
duration: 300
}
}
Component {
id: libraryDelegate
Item {
implicitWidth: ListView.view.width
height: selectedLibrary == libraryType ? 50 : 0
property bool rightMenu: false
property bool selected: selectionModel.hasSelection && selectionModel.currentIndex == innerModel.index(index, 0)
property bool fileValidation: {
if (filePath)
fileHelper.validate(filePath)
else
false
}
Rectangle {
id: itemBackground
color: Kirigami.Theme.backgroundColor
anchors.fill: parent
Binding on color {
when: dragHandler.containsMouse || selected
value: Kirigami.Theme.highlightColor
}
}
Controls.ItemDelegate {
id: listItem
implicitWidth: libraryList.width
height: selectedLibrary == libraryType ? 50 : 0
text: title
/* subtitle: { */
/* if (libraryType == "song") */
/* author */
/* else if (fileValidation) */
/* filePath; */
/* else */
/* "file is missing" */
/* } */
icon.source: itemIcon
icon.width: Kirigami.Units.gridUnit
icon.height: Kirigami.Units.gridUnit
/* supportsMouseEvents: false */
/* textColor: { */
/* if (selectedLibrary == "song") */
/* Kirigami.Theme.textColor; */
/* else if (fileValidation) { */
/* Kirigami.Theme.textColor; */
/* } */
/* else */
/* "red" */
/* } */
/* Binding on textColor { */
/* when: dragHandler.containsMouse || */
/* (selectionModel.hasSelection && */
/* selectionModel.isSelected(proxyModel.idx(index))) */
/* value: Kirigami.Theme.highlightedTextColor */
/* } */
Behavior on height {
NumberAnimation {
easing.type: Easing.OutCubic
duration: 300
}
}
Drag.active: dragHandler.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
Drag.keys: [ "library" ]
states: State {
name: "dragged"
when: listItem.Drag.active
PropertyChanges {
target: listItem
x: x
y: y
width: width
height: height
}
ParentChange {
target: listItem
parent: rootApp.overlay
}
}
}
MouseArea {
id: dragHandler
anchors.fill: parent
hoverEnabled: true
Controls.ToolTip {
text: {
if (libraryType == "song")
title + "\n" + author
else if (fileValidation)
title + "\n" + filePath;
else
"file is missing"
}
}
drag {
target: listItem
onActiveChanged: {
if (dragHandler.drag.active) {
dragItemIndex = index;
dragItemType = libraryType;
draggedLibraryItem = self;
} else {
listItem.Drag.drop();
dragHighlightLine.visible = false;
}
}
filterChildren: true
threshold: 10
/* onDropped: dragHighlightLine.visible = false; */
}
MouseArea {
id: clickHandler
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.RightButton) {
if(selectionModel.selectedIndexes.length <= 1)
selectionModel.select(innerModel.index(index),
ItemSelectionModel.ClearAndSelect);
rightClickMenu.popup()
}
else if ((mouse.button === Qt.LeftButton) &&
(mouse.modifiers === Qt.ShiftModifier)) {
if (libraryList.currentIndex < index) {
for (let i = libraryList.currentIndex; i <= index; i++) {
selectionModel.select(innerModel.index(i),
ItemSelectionModel.Select);
}
}
else {
for (let i = index; i <= libraryList.currentIndex; i++) {
selectionModel.select(innerModel.index(i),
ItemSelectionModel.Select);
}
}
console.log(selectionModel.selectedIndexes);
} else {
selectionModel.select(innerModel.index(index),
ItemSelectionModel.ClearAndSelect);
libraryList.currentIndex = index;
}
}
onDoubleClicked: {
libraryList.currentIndex = index;
if (!editMode)
editMode = true;
editSwitch(index, libraryType);
}
}
}
Controls.Menu {
id: rightClickMenu
x: clickHandler.mouseX
y: clickHandler.mouseY + 10
Kirigami.Action {
text: "delete"
onTriggered: {
var selection = [];
var length = selectionModel.selectedIndexes.length;
for (let i = 0; i < length; i++) {
selection.push(selectionModel.selectedIndexes[i].row);
}
root.deleteItemFunction(selection);
}
}
}
}
}
Kirigami.WheelHandler {
id: wheelHandler
target: libraryList
filterMouseEvents: true
keyNavigationEnabled: true
}
Controls.ScrollBar.vertical: Controls.ScrollBar {
active: hovered || pressed
}
function selectItems(row) {
let currentRow = selectionModel.selectedIndexes[0].row;
if (row === currentRow)
return;
if (row > currentRow) {
for (var i = currentRow; i <= row; i++) {
let idx = innerModel.idx(i);
selectionModel.select(idx, ItemSelectionModel.Select);
}
}
else {
for (var i = row; i <= currentRow; i++) {
let idx = innerModel.idx(i);
selectionModel.select(idx, ItemSelectionModel.Select);
}
}
}
}
}