adding a better leftdock system based off simpler model
This commit is contained in:
parent
52bbec5ac5
commit
b4f6069daa
4 changed files with 507 additions and 9 deletions
438
src/qml/presenter/ServiceList.qml
Normal file
438
src/qml/presenter/ServiceList.qml
Normal file
|
@ -0,0 +1,438 @@
|
|||
import QtQuick 2.13
|
||||
/* import QtQuick.Dialogs 1.0 */
|
||||
import QtQuick.Controls 2.0 as Controls
|
||||
/* import QtQuick.Window 2.13 */
|
||||
import QtQuick.Layouts 1.2
|
||||
/* import QtQuick.Shapes 1.15 */
|
||||
import QtQml.Models 2.12
|
||||
/* import QtMultimedia 5.15 */
|
||||
/* import QtAudioEngine 1.15 */
|
||||
import org.kde.kirigami 2.13 as Kirigami
|
||||
import "./" as Presenter
|
||||
import org.presenter 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var selectedItem: serviceItemList.selected
|
||||
property var hlItem
|
||||
|
||||
Rectangle {
|
||||
id: headerBackground
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
height: 40
|
||||
opacity: 1.0
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.Heading {
|
||||
id: serviceTitle
|
||||
text: "Service List"
|
||||
anchors.centerIn: headerBackground
|
||||
padding: 5
|
||||
level: 3
|
||||
}
|
||||
}
|
||||
|
||||
DropArea {
|
||||
id: serviceDropEnd
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
onDropped: (drag) => {
|
||||
print("DROPPED AT END");
|
||||
appendItem(dragItemTitle,
|
||||
dragItemType,
|
||||
dragItemBackground,
|
||||
dragItemBackgroundType,
|
||||
dragItemText,
|
||||
dragItemIndex);
|
||||
dropHighlightLine.visible = false;
|
||||
}
|
||||
|
||||
keys: ["library"]
|
||||
|
||||
onEntered: (drag) => {
|
||||
if (drag.keys[0] === "library") {
|
||||
dropHighlightLine.visible = true;
|
||||
var lastItem = serviceItemList.itemAtIndex(serviceItemModel.rowCount() - 1);
|
||||
dropHighlightLine.y = lastItem.y + lastItem.height;
|
||||
}
|
||||
}
|
||||
|
||||
/* onExited: dropHighlightLine.visible = false; */
|
||||
|
||||
ListView {
|
||||
id: serviceItemList
|
||||
anchors.fill: parent
|
||||
/* model: serviceItemModel */
|
||||
/* delegate: Kirigami.DelegateRecycler { */
|
||||
/* width: serviceItemList.width */
|
||||
/* sourceComponent: itemDelegate */
|
||||
/* } */
|
||||
clip: true
|
||||
spacing: 3
|
||||
property int indexDragged
|
||||
property int moveToIndex
|
||||
property int draggedY
|
||||
|
||||
addDisplaced: Transition {
|
||||
NumberAnimation {properties: "x, y"; duration: 100}
|
||||
}
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation { properties: "x, y"; duration: 100 }
|
||||
}
|
||||
remove: Transition {
|
||||
NumberAnimation { properties: "x, y"; duration: 100 }
|
||||
NumberAnimation { properties: "opacity"; duration: 100 }
|
||||
}
|
||||
|
||||
removeDisplaced: Transition {
|
||||
NumberAnimation { properties: "x, y"; duration: 100 }
|
||||
}
|
||||
|
||||
displaced: Transition {
|
||||
NumberAnimation {properties: "x, y"; duration: 100}
|
||||
}
|
||||
|
||||
model: serviceItemModel
|
||||
|
||||
delegate: DropArea {
|
||||
id: serviceDrop
|
||||
implicitWidth: serviceItemList.width
|
||||
height: 50
|
||||
/* enabled: false */
|
||||
|
||||
onEntered: (drag) => {
|
||||
if (drag.keys[0] === "library") {
|
||||
dropHighlightLine.visible = true;
|
||||
dropHighlightLine.y = y - 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* onExited: dropHighlightLine.visible = false; */
|
||||
|
||||
onDropped: (drag) => {
|
||||
print("DROPPED IN ITEM AREA: " + drag.keys);
|
||||
print(dragItemIndex + " " + index);
|
||||
const hlIndex = serviceItemList.currentIndex;
|
||||
if (drag.keys[0] === "library") {
|
||||
addItem(index,
|
||||
dragItemTitle,
|
||||
dragItemType,
|
||||
dragItemBackground,
|
||||
dragItemBackgroundType,
|
||||
dragItemText,
|
||||
dragItemIndex);
|
||||
} else if (drag.keys[0] === "serviceitem") {
|
||||
serviceItemModel.move(serviceItemList.indexDragged,
|
||||
serviceItemList.moveToIndex);
|
||||
serviceItemList.currentIndex = moveToIndex;
|
||||
}
|
||||
dropHighlightLine.visible = false;
|
||||
}
|
||||
|
||||
keys: ["library","serviceitem"]
|
||||
|
||||
Kirigami.BasicListItem {
|
||||
id: visServiceItem
|
||||
width: serviceDrop.width
|
||||
height: serviceDrop.height
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
label: name
|
||||
subtitle: type
|
||||
hoverEnabled: false
|
||||
supportsMouseEvents: false
|
||||
backgroundColor: {
|
||||
if (serviceItemList.currentIndex === index)
|
||||
Kirigami.Theme.highlightColor;
|
||||
else if (mouseHandler.containsMouse)
|
||||
Kirigami.Theme.hoverColor;
|
||||
else
|
||||
Kirigami.Theme.backgroundColor;
|
||||
}
|
||||
textColor: {
|
||||
if (serviceItemList.currentIndex === index ||
|
||||
mouseHandler.containsMouse)
|
||||
activeTextColor;
|
||||
else
|
||||
Kirigami.Theme.textColor;
|
||||
}
|
||||
|
||||
onYChanged: serviceItemList.updateDrag(Math.round(y));
|
||||
|
||||
states: [
|
||||
State {
|
||||
when: mouseHandler.drag.active
|
||||
ParentChange {
|
||||
target: visServiceItem
|
||||
parent: serviceItemList
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: visServiceItem
|
||||
backgroundColor: Kirigami.Theme.backgroundColor
|
||||
textColor: Kirigami.Theme.textColor
|
||||
anchors.verticalCenter: undefined
|
||||
anchors.horizontalCenter: undefined
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
/* Drag.dragType: Drag.Automatic */
|
||||
Drag.active: mouseHandler.drag.active
|
||||
Drag.hotSpot.x: width / 2
|
||||
Drag.hotSpot.y: height / 2
|
||||
Drag.keys: ["serviceitem"]
|
||||
|
||||
MouseArea {
|
||||
id: mouseHandler
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
|
||||
drag {
|
||||
target: visServiceItem
|
||||
axis: Drag.YAxis
|
||||
/* minimumY: root.y */
|
||||
/* maximumY: serviceItemList.height - serviceDrop.height */
|
||||
smoothed: false
|
||||
}
|
||||
|
||||
drag.onActiveChanged: {
|
||||
if (mouseHandler.drag.active) {
|
||||
serviceItemList.indexDragged = index;
|
||||
}
|
||||
}
|
||||
|
||||
/* onPositionChanged: { */
|
||||
/* if (!pressed) { */
|
||||
/* return; */
|
||||
/* } */
|
||||
/* mouseArea.arrangeItem(); */
|
||||
/* } */
|
||||
|
||||
onPressed: {
|
||||
serviceItemList.interactive = false;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.RightButton)
|
||||
rightClickMenu.popup();
|
||||
else {
|
||||
serviceItemList.currentIndex = index;
|
||||
/* currentServiceItem = index; */
|
||||
/* changeItem(index); */
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
showPassiveNotification("Double Clicked")
|
||||
serviceItemList.currentIndex = index;
|
||||
currentServiceItem = index;
|
||||
changeServiceItem(index);
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
print("should drop");
|
||||
visServiceItem.Drag.drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controls.Menu {
|
||||
id: rightClickMenu
|
||||
x: mouseHandler.mouseX
|
||||
y: mouseHandler.mouseY + 10
|
||||
Kirigami.Action {
|
||||
text: "delete"
|
||||
onTriggered: removeItem(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Kirigami.WheelHandler {
|
||||
id: wheelHandler
|
||||
target: serviceItemList
|
||||
filterMouseEvents: true
|
||||
keyNavigationEnabled: true
|
||||
}
|
||||
|
||||
Controls.ScrollBar.vertical: Controls.ScrollBar {
|
||||
anchors.right: serviceItemList.right
|
||||
anchors.rightMargin: 0
|
||||
active: hovered || pressed
|
||||
}
|
||||
|
||||
function updateDrag(y) {
|
||||
if (moveToIndex === serviceItemList.indexAt(0,y))
|
||||
return;
|
||||
else
|
||||
moveToIndex = serviceItemList.indexAt(0,y);
|
||||
moveRequested(indexDragged, moveToIndex);
|
||||
}
|
||||
|
||||
function moveRequested(oldIndex, newIndex) {
|
||||
if (newIndex === oldIndex)
|
||||
return;
|
||||
if (newIndex === -1)
|
||||
newIndex = 0;
|
||||
print("moveRequested: ", oldIndex, newIndex);
|
||||
serviceItemModel.move(oldIndex, newIndex);
|
||||
indexDragged = newIndex;
|
||||
serviceItemList.currentIndex = newIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: dropHighlightLine
|
||||
width: parent.width
|
||||
height: 4
|
||||
color: Kirigami.Theme.hoverColor
|
||||
visible: false
|
||||
|
||||
}
|
||||
Canvas {
|
||||
/* asynchronous: true; */
|
||||
x: dropHighlightLine.width - 8
|
||||
y: dropHighlightLine.y - 17
|
||||
z: 1
|
||||
width: 100; height: 100;
|
||||
contextType: "2d"
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.fillStyle = Kirigami.Theme.hoverColor;
|
||||
ctx.rotate(30);
|
||||
ctx.transform(0.8, 0, 0, 0.8, 0, 30)
|
||||
ctx.path = tearDropPath;
|
||||
ctx.fill();
|
||||
}
|
||||
visible: dropHighlightLine.visible
|
||||
}
|
||||
Path {
|
||||
id: tearDropPath
|
||||
startX: dropHighlightLine.width
|
||||
startY: dropHighlightLine.y + 4
|
||||
PathSvg {
|
||||
path: "M15 3
|
||||
Q16.5 6.8 25 18
|
||||
A12.8 12.8 0 1 1 5 18
|
||||
Q13.5 6.8 15 3z"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.ActionToolBar {
|
||||
id: serviceToolBar
|
||||
Layout.fillWidth: true
|
||||
opacity: 1.0
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
/* text: "Up" */
|
||||
icon.name: "arrow-up"
|
||||
onTriggered: {
|
||||
const oldid = serviceItemList.currentIndex;
|
||||
if (oldid <= 0)
|
||||
{
|
||||
showPassiveNotification("wow stop trying to go nego");
|
||||
return;
|
||||
}
|
||||
const newid = serviceItemList.currentIndex - 1;
|
||||
showPassiveNotification(oldid + " " + newid);
|
||||
showPassiveNotification("Up");
|
||||
const ans = serviceItemModel.move(oldid, newid);
|
||||
if (ans)
|
||||
{
|
||||
serviceItemList.currentIndex = newid;
|
||||
showPassiveNotification("move was successful, newid: "
|
||||
+ serviceItemList.currentIndex);
|
||||
}
|
||||
else
|
||||
showPassiveNotification("move was unsuccessful")
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
/* text: "Down" */
|
||||
icon.name: "arrow-down"
|
||||
onTriggered: {
|
||||
const oldid = serviceItemList.currentIndex;
|
||||
if (oldid + 1 >= serviceItemList.count)
|
||||
{
|
||||
showPassiveNotification("wow you dummy you can't got further down");
|
||||
return;
|
||||
};
|
||||
const newid = findId(serviceItemList.currentIndex + 2);
|
||||
showPassiveNotification(oldid + " " + newid);
|
||||
showPassiveNotification("Down");
|
||||
const ans = serviceItemModel.move(oldid, newid);
|
||||
if (ans)
|
||||
{
|
||||
serviceItemList.currentIndex = newid - 1;
|
||||
showPassiveNotification("move was successful, newid: "
|
||||
+ serviceItemList.currentIndex);
|
||||
}
|
||||
else
|
||||
showPassiveNotification("move was unsuccessful, newid: "
|
||||
+ newid);
|
||||
|
||||
function findId(id) {
|
||||
if (id >= serviceItemList.count)
|
||||
return serviceItemList.count;
|
||||
else
|
||||
return id;
|
||||
}
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
/* text: "Remove" */
|
||||
icon.name: "delete"
|
||||
onTriggered: {
|
||||
showPassiveNotification("remove");
|
||||
removeItem(serviceItemList.currentIndex);
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
totalServiceItems = serviceItemList.count;
|
||||
print("THE TOTAL SERVICE ITEMS: " + totalServiceItems);
|
||||
}
|
||||
|
||||
function removeItem(index) {
|
||||
serviceItemModel.removeItem(index);
|
||||
totalServiceItems--;
|
||||
}
|
||||
|
||||
function addItem(index, name, type,
|
||||
background, backgroundType, text, itemID) {
|
||||
const newtext = songsqlmodel.getLyricList(itemID);
|
||||
print("adding: " + name + " of type " + type);
|
||||
serviceItemModel.insertItem(index, name,
|
||||
type, background,
|
||||
backgroundType, newtext);
|
||||
totalServiceItems++;
|
||||
}
|
||||
|
||||
function appendItem(name, type, background, backgroundType, text, itemID) {
|
||||
print("adding: " + name + " of type " + type);
|
||||
let lyrics;
|
||||
if (type === "song") {
|
||||
print(itemID);
|
||||
lyrics = songsqlmodel.getLyricList(itemID);
|
||||
print(lyrics);
|
||||
}
|
||||
|
||||
print(background);
|
||||
print(backgroundType);
|
||||
|
||||
serviceItemModel.addItem(name, type, background,
|
||||
backgroundType, lyrics);
|
||||
totalServiceItems++;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
<file>qml/main.qml</file>
|
||||
<file>qml/presenter/qmldir</file>
|
||||
<file>qml/presenter/LeftDock.qml</file>
|
||||
<file>qml/presenter/ServiceList.qml</file>
|
||||
<file>qml/presenter/MainWindow.qml</file>
|
||||
<file>qml/presenter/Library.qml</file>
|
||||
<file>qml/presenter/Header.qml</file>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
ServiceItemModel::ServiceItemModel(QObject *parent)
|
||||
: QAbstractListModel(parent) {
|
||||
addItem(new ServiceItem("10,000 Resons", "song",
|
||||
addItem(new ServiceItem("10,000 Reasons", "song",
|
||||
"file:/home/chris/nextcloud/tfc/openlp/CMG - Nature King 21.jpg",
|
||||
"image", QStringList("Yip Yip")));
|
||||
addItem(new ServiceItem("Marvelous Light", "song",
|
||||
|
@ -114,6 +114,23 @@ Qt::ItemFlags ServiceItemModel::flags(const QModelIndex &index) const {
|
|||
return Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
}
|
||||
|
||||
// int ServiceItemModel::index(int row, int column, const QModelIndex &parent) {
|
||||
// if (!hasIndex(row, column, parent))
|
||||
// return QModelIndex();
|
||||
|
||||
// ServiceItem *parentItem;
|
||||
|
||||
// if (!parent.isValid())
|
||||
// parentItem = rootItem;
|
||||
// else
|
||||
// parentItem = static_cast<ServiceItem*>(parent.internalPointer());
|
||||
|
||||
// ServiceItem *childItem = parentItem->child(row);
|
||||
// if (childItem)
|
||||
// return createIndex(row, column, childItem);
|
||||
// return QModelIndex();
|
||||
// }
|
||||
|
||||
void ServiceItemModel::addItem(ServiceItem *item) {
|
||||
const int index = m_items.size();
|
||||
qDebug() << index;
|
||||
|
@ -181,23 +198,59 @@ void ServiceItemModel::removeItem(int index) {
|
|||
bool ServiceItemModel::move(int sourceIndex, int destIndex) {
|
||||
qDebug() << index(sourceIndex).row();
|
||||
qDebug() << index(destIndex).row();
|
||||
// beginResetModel();
|
||||
QModelIndex parent = index(sourceIndex).parent();
|
||||
if (sourceIndex >= 0 && sourceIndex != destIndex &&
|
||||
destIndex >= -1 && destIndex < rowCount() &&
|
||||
destIndex >= -1 && destIndex <= rowCount() &&
|
||||
sourceIndex < rowCount()) {
|
||||
qDebug() << "starting move: " << "source: " << sourceIndex << "dest: " << destIndex;
|
||||
bool begsuc = beginMoveRows(QModelIndex(), sourceIndex,
|
||||
sourceIndex, QModelIndex(), destIndex);
|
||||
bool begsuc = beginMoveRows(parent, sourceIndex,
|
||||
sourceIndex, parent, destIndex);
|
||||
if (begsuc) {
|
||||
if (destIndex = -1)
|
||||
if (destIndex == -1)
|
||||
{
|
||||
qDebug() << "dest was too small, moving to row 0";
|
||||
m_items.move(sourceIndex, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "dest was not too small";
|
||||
if (destIndex >= m_items.size())
|
||||
{
|
||||
qDebug() << "destIndex too big, moving to end";
|
||||
m_items.move(sourceIndex, m_items.size() - 1);
|
||||
}
|
||||
else
|
||||
m_items.move(sourceIndex, destIndex);
|
||||
}
|
||||
endMoveRows();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
qDebug() << "Can't move row, not sure why, sourceIndex: "
|
||||
<< sourceIndex << " destIndex: " << destIndex;
|
||||
return false;
|
||||
}
|
||||
qDebug() << "Can't move row, invalid options, sourceIndex: "
|
||||
<< sourceIndex << " destIndex: " << destIndex;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServiceItemModel::move(int sourceIndex, int destIndex, bool simple) {
|
||||
qDebug() << index(sourceIndex).row();
|
||||
qDebug() << index(destIndex).row();
|
||||
QModelIndex parent = index(sourceIndex).parent();
|
||||
|
||||
if (simple)
|
||||
{
|
||||
if (moveRow(parent, sourceIndex, parent, destIndex))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
qDebug() << "not sure...";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariantMap ServiceItemModel::getItem(int index) const {
|
||||
|
|
|
@ -24,10 +24,15 @@ public:
|
|||
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
// int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
// Q_INVOKABLE int index(int row, int column,
|
||||
// const QModelIndex &parent = QModelIndex()) const override;
|
||||
// Q_INVOKABLE QModelIndex parent(const QModelIndex &index) const override;
|
||||
|
||||
// Editable:
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
|
@ -56,6 +61,7 @@ public:
|
|||
const QString &backgroundType, const QStringList &text);
|
||||
Q_INVOKABLE void removeItem(int index);
|
||||
Q_INVOKABLE bool move(int sourceIndex, int destIndex);
|
||||
Q_INVOKABLE bool move(int sourceIndex, int destIndex, bool simple);
|
||||
Q_INVOKABLE QVariantMap getItem(int index) const;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue