mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
homescreens/halcyon: Add ability to create folders by dragging
This commit is contained in:
parent
d3054b1983
commit
51f558b4a3
5 changed files with 281 additions and 97 deletions
|
|
@ -24,6 +24,8 @@ Item {
|
||||||
property real leftPadding
|
property real leftPadding
|
||||||
property real rightPadding
|
property real rightPadding
|
||||||
|
|
||||||
|
property real dragFolderAnimationProgress: 0
|
||||||
|
|
||||||
// whether this delegate is a folder
|
// whether this delegate is a folder
|
||||||
property bool isFolder
|
property bool isFolder
|
||||||
|
|
||||||
|
|
@ -45,6 +47,18 @@ Item {
|
||||||
Drag.hotSpot.x: delegate.width / 2
|
Drag.hotSpot.x: delegate.width / 2
|
||||||
Drag.hotSpot.y: delegate.height / 2
|
Drag.hotSpot.y: delegate.height / 2
|
||||||
|
|
||||||
|
// close context menu if drag move
|
||||||
|
onXChanged: {
|
||||||
|
if (dialogLoader.item) {
|
||||||
|
dialogLoader.item.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onYChanged: {
|
||||||
|
if (dialogLoader.item) {
|
||||||
|
dialogLoader.item.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function openContextMenu() {
|
function openContextMenu() {
|
||||||
dialogLoader.active = true;
|
dialogLoader.active = true;
|
||||||
dialogLoader.item.open();
|
dialogLoader.item.open();
|
||||||
|
|
@ -88,7 +102,7 @@ Item {
|
||||||
icon.name: "emblem-favorite"
|
icon.name: "emblem-favorite"
|
||||||
text: i18n("Remove from favourites")
|
text: i18n("Remove from favourites")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Halcyon.PinnedModel.removeApp(model.index);
|
Halcyon.PinnedModel.removeEntry(model.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClosed: dialogLoader.active = false
|
onClosed: dialogLoader.active = false
|
||||||
|
|
@ -107,7 +121,7 @@ Item {
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
onClicked: (mouse.button === Qt.RightButton) ? openContextMenu() : launch();
|
onClicked: (mouse.button === Qt.RightButton) ? openContextMenu() : launch();
|
||||||
onReleased: {
|
onReleased: {
|
||||||
delegate.parent.Drag.drop();
|
delegate.Drag.drop();
|
||||||
inDrag = false;
|
inDrag = false;
|
||||||
}
|
}
|
||||||
onPressAndHold: { inDrag = true; openContextMenu() }
|
onPressAndHold: { inDrag = true; openContextMenu() }
|
||||||
|
|
@ -198,28 +212,47 @@ Item {
|
||||||
Component {
|
Component {
|
||||||
id: appIconComponent
|
id: appIconComponent
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
Item {
|
||||||
usesPlasmaTheme: false
|
|
||||||
source: delegate.isFolder ? 'document-open-folder' : delegate.applicationIcon
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors {
|
anchors.fill: parent
|
||||||
horizontalCenter: parent.horizontalCenter
|
anchors.margins: PlasmaCore.Units.smallSpacing
|
||||||
bottom: parent.bottom
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
}
|
radius: PlasmaCore.Units.smallSpacing
|
||||||
visible: application ? application.running : false
|
opacity: delegate.dragFolderAnimationProgress
|
||||||
radius: width
|
|
||||||
width: PlasmaCore.Units.smallSpacing
|
|
||||||
height: width
|
|
||||||
color: PlasmaCore.Theme.highlightColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
PlasmaCore.IconItem {
|
||||||
layer.effect: DropShadow {
|
id: icon
|
||||||
verticalOffset: 1
|
anchors.fill: parent
|
||||||
radius: 4
|
usesPlasmaTheme: false
|
||||||
samples: 6
|
source: delegate.isFolder ? 'document-open-folder' : delegate.applicationIcon
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
|
||||||
|
transform: Scale {
|
||||||
|
origin.x: icon.width / 2
|
||||||
|
origin.y: icon.height / 2
|
||||||
|
xScale: 1 - delegate.dragFolderAnimationProgress * 0.5
|
||||||
|
yScale: 1 - delegate.dragFolderAnimationProgress * 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
visible: application ? application.running : false
|
||||||
|
radius: width
|
||||||
|
width: PlasmaCore.Units.smallSpacing
|
||||||
|
height: width
|
||||||
|
color: PlasmaCore.Theme.highlightColor
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,34 +262,42 @@ Item {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: rect
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: PlasmaCore.Units.smallSpacing
|
anchors.margins: PlasmaCore.Units.smallSpacing
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
radius: PlasmaCore.Units.smallSpacing
|
radius: PlasmaCore.Units.smallSpacing
|
||||||
|
|
||||||
Grid {
|
transform: Scale {
|
||||||
id: grid
|
origin.x: rect.width / 2
|
||||||
anchors.fill: parent
|
origin.y: rect.height / 2
|
||||||
anchors.margins: PlasmaCore.Units.smallSpacing
|
xScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
||||||
columns: 2
|
yScale: 1 + delegate.dragFolderAnimationProgress * 0.5
|
||||||
spacing: PlasmaCore.Units.smallSpacing
|
}
|
||||||
|
}
|
||||||
property var previews: model.folder.appPreviews
|
|
||||||
|
Grid {
|
||||||
Repeater {
|
id: grid
|
||||||
model: grid.previews
|
anchors.fill: parent
|
||||||
delegate: Kirigami.Icon {
|
anchors.margins: PlasmaCore.Units.smallSpacing * 2
|
||||||
implicitWidth: (grid.width - PlasmaCore.Units.smallSpacing) / 2
|
columns: 2
|
||||||
implicitHeight: (grid.width - PlasmaCore.Units.smallSpacing) / 2
|
spacing: PlasmaCore.Units.smallSpacing
|
||||||
source: modelData.icon
|
|
||||||
|
property var previews: model.folder.appPreviews
|
||||||
layer.enabled: true
|
|
||||||
layer.effect: DropShadow {
|
Repeater {
|
||||||
verticalOffset: 1
|
model: grid.previews
|
||||||
radius: 4
|
delegate: Kirigami.Icon {
|
||||||
samples: 3
|
implicitWidth: (grid.width - PlasmaCore.Units.smallSpacing) / 2
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
implicitHeight: (grid.width - PlasmaCore.Units.smallSpacing) / 2
|
||||||
}
|
source: modelData.icon
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 3
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,18 @@ MobileShell.GridView {
|
||||||
id: root
|
id: root
|
||||||
required property var searchWidget
|
required property var searchWidget
|
||||||
|
|
||||||
signal openConfigureRequested()
|
|
||||||
signal requestOpenFolder(Halcyon.ApplicationFolder folder)
|
|
||||||
|
|
||||||
// don't set anchors.margins since we want everywhere to be draggable
|
// don't set anchors.margins since we want everywhere to be draggable
|
||||||
required property real leftMargin
|
required property real leftMargin
|
||||||
required property real rightMargin
|
required property real rightMargin
|
||||||
required property bool twoColumn
|
required property bool twoColumn
|
||||||
|
|
||||||
|
signal openConfigureRequested()
|
||||||
|
signal requestOpenFolder(Halcyon.ApplicationFolder folder)
|
||||||
|
|
||||||
// search widget open gesture
|
// search widget open gesture
|
||||||
property bool openingSearchWidget: false
|
property bool openingSearchWidget: false
|
||||||
property real oldVerticalOvershoot: verticalOvershoot
|
property real oldVerticalOvershoot: verticalOvershoot
|
||||||
|
|
||||||
onVerticalOvershootChanged: {
|
onVerticalOvershootChanged: {
|
||||||
if (dragging && verticalOvershoot < 0) {
|
if (dragging && verticalOvershoot < 0) {
|
||||||
if (!openingSearchWidget) {
|
if (!openingSearchWidget) {
|
||||||
|
|
@ -75,27 +76,134 @@ MobileShell.GridView {
|
||||||
id: visualModel
|
id: visualModel
|
||||||
model: Halcyon.PinnedModel
|
model: Halcyon.PinnedModel
|
||||||
|
|
||||||
delegate: DropArea {
|
delegate: Item {
|
||||||
id: delegateRoot
|
id: delegateRoot
|
||||||
property int modelIndex
|
|
||||||
property int visualIndex: DelegateModel.itemsIndex
|
property int visualIndex: DelegateModel.itemsIndex
|
||||||
|
|
||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
|
||||||
onEntered: (drag) => {
|
function moveDragToCurrentPos(from, to) {
|
||||||
let from = (drag.source as MobileShell.BaseItem).visualIndex;
|
if (from !== to) {
|
||||||
let to = appDelegate.visualIndex;
|
console.log(from + ' ' + to)
|
||||||
visualModel.items.move(from, to);
|
visualModel.items.move(from, to);
|
||||||
Halcyon.PinnedModel.moveEntry(from, to);
|
Halcyon.PinnedModel.moveEntry(from, to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//onDropped: (drag) => {
|
function topDragEnter(drag) {
|
||||||
//let from = modelIndex;
|
if (transitionAnim.running || appDelegate.drag.active) return; // don't do anything when reordering
|
||||||
//let to = (drag.source as MobileShell.BaseItem).visualIndex
|
|
||||||
//Halcyon.PinnedModel.moveEntry(from, to);
|
let fromIndex = drag.source.visualIndex;
|
||||||
//}
|
let delegateVisualIndex = appDelegate.visualIndex;
|
||||||
|
let reorderIndex = -1;
|
||||||
|
|
||||||
|
if (fromIndex < delegateVisualIndex) { // dragged item from above
|
||||||
|
// move to spot above
|
||||||
|
reorderIndex = delegateVisualIndex - (root.twoColumn ? 2 : 1);
|
||||||
|
} else { // dragged item from below
|
||||||
|
// move to current spot
|
||||||
|
reorderIndex = delegateVisualIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reorderIndex >= 0 && reorderIndex < root.count) {
|
||||||
|
delegateRoot.moveDragToCurrentPos(fromIndex, reorderIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bottomDragEnter(drag) {
|
||||||
|
if (transitionAnim.running || appDelegate.drag.active) return; // don't do anything when reordering
|
||||||
|
|
||||||
|
let fromIndex = drag.source.visualIndex;
|
||||||
|
let delegateVisualIndex = appDelegate.visualIndex;
|
||||||
|
let reorderIndex = -1;
|
||||||
|
|
||||||
|
if (fromIndex < delegateVisualIndex) { // dragged item from above
|
||||||
|
// move to current spot
|
||||||
|
reorderIndex = delegateVisualIndex;
|
||||||
|
} else { // dragged item from below
|
||||||
|
// move to spot below
|
||||||
|
reorderIndex = delegateVisualIndex + (root.twoColumn ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reorderIndex >= 0 && reorderIndex < root.count) {
|
||||||
|
delegateRoot.moveDragToCurrentPos(fromIndex, reorderIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// top drop area
|
||||||
|
DropArea {
|
||||||
|
id: topDropArea
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: leftDropArea.right
|
||||||
|
anchors.right: rightDropArea.left
|
||||||
|
height: delegateRoot.height * 0.2
|
||||||
|
onEntered: (drag) => delegateRoot.topDragEnter(drag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom drop area
|
||||||
|
DropArea {
|
||||||
|
id: bottomDropArea
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: leftDropArea.right
|
||||||
|
anchors.right: rightDropArea.left
|
||||||
|
height: delegateRoot.height * 0.2
|
||||||
|
onEntered: (drag) => delegateRoot.bottomDragEnter(drag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// left drop area
|
||||||
|
DropArea {
|
||||||
|
id: leftDropArea
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: root.twoColumn ? Math.max(appDelegate.leftPadding, delegateRoot.width * 0.1) : 0
|
||||||
|
onEntered: (drag) => delegateRoot.topDragEnter(drag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// right drop area
|
||||||
|
DropArea {
|
||||||
|
id: rightDropArea
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
width: root.twoColumn ? Math.max(appDelegate.rightPadding, delegateRoot.width * 0.1) : 0
|
||||||
|
onEntered: (drag) => delegateRoot.bottomDragEnter(drag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// folder drop area
|
||||||
|
DropArea {
|
||||||
|
anchors.top: topDropArea.bottom
|
||||||
|
anchors.bottom: bottomDropArea.top
|
||||||
|
anchors.left: leftDropArea.right
|
||||||
|
anchors.right: rightDropArea.left
|
||||||
|
onEntered: (drag) => {
|
||||||
|
if (transitionAnim.running || appDelegate.drag.active) return; // don't do anything when reordering
|
||||||
|
folderAnim.to = 1;
|
||||||
|
folderAnim.restart();
|
||||||
|
}
|
||||||
|
onExited: () => {
|
||||||
|
folderAnim.to = 0;
|
||||||
|
folderAnim.restart();
|
||||||
|
}
|
||||||
|
onDropped: (drop) => {
|
||||||
|
if (transitionAnim.running || appDelegate.drag.active) return; // don't do anything when reordering
|
||||||
|
if (appDelegate.isFolder) {
|
||||||
|
Halcyon.PinnedModel.addAppToFolder(drop.source.visualIndex, appDelegate.visualIndex);
|
||||||
|
} else {
|
||||||
|
Halcyon.PinnedModel.createFolderFromApps(drop.source.visualIndex, appDelegate.visualIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
id: folderAnim
|
||||||
|
target: appDelegate
|
||||||
|
properties: "dragFolderAnimationProgress"
|
||||||
|
duration: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// actual visual delegate
|
||||||
FavoritesAppDelegate {
|
FavoritesAppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
visualIndex: delegateRoot.visualIndex
|
visualIndex: delegateRoot.visualIndex
|
||||||
|
|
@ -139,6 +247,7 @@ MobileShell.GridView {
|
||||||
// animations
|
// animations
|
||||||
displaced: Transition {
|
displaced: Transition {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
|
id: transitionAnim
|
||||||
properties: "x,y"
|
properties: "x,y"
|
||||||
easing.type: Easing.OutQuad
|
easing.type: Easing.OutQuad
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,28 +98,23 @@ MobileShell.GridView {
|
||||||
id: visualModel
|
id: visualModel
|
||||||
model: root.folderModel
|
model: root.folderModel
|
||||||
|
|
||||||
delegate: DropArea {
|
delegate: Item {
|
||||||
id: delegateRoot
|
id: delegateRoot
|
||||||
property var application: model.application
|
|
||||||
|
|
||||||
property int modelIndex
|
|
||||||
property int visualIndex: DelegateModel.itemsIndex
|
|
||||||
|
|
||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
|
||||||
onEntered: (drag) => {
|
property var application: model.application
|
||||||
let from = (drag.source as MobileShell.BaseItem).visualIndex;
|
property int visualIndex: DelegateModel.itemsIndex
|
||||||
let to = appDelegate.visualIndex;
|
|
||||||
visualModel.items.move(from, to);
|
|
||||||
root.folder.moveEntry(from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
//onDropped: (drag) => {
|
DropArea {
|
||||||
//let from = modelIndex;
|
anchors.fill: parent
|
||||||
//let to = (drag.source as MobileShell.BaseItem).visualIndex
|
onEntered: (drag) => {
|
||||||
//Halcyon.PinnedModel.moveEntry(from, to);
|
let from = drag.source.visualIndex;
|
||||||
//}
|
let to = appDelegate.visualIndex;
|
||||||
|
visualModel.items.move(from, to);
|
||||||
|
root.folder.moveEntry(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FavoritesAppDelegate {
|
FavoritesAppDelegate {
|
||||||
id: appDelegate
|
id: appDelegate
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
PinnedModel::PinnedModel(QObject *parent, Plasma::Applet *applet)
|
PinnedModel::PinnedModel(QObject *parent, Plasma::Applet *applet)
|
||||||
: QAbstractListModel{parent}
|
: QAbstractListModel{parent}
|
||||||
, m_applet{applet}
|
, m_applet{applet}
|
||||||
|
|
@ -60,21 +62,6 @@ void PinnedModel::addApp(const QString &storageId, int row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedModel::removeApp(int row)
|
|
||||||
{
|
|
||||||
if (row < 0 || row >= m_applications.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), row, row);
|
|
||||||
m_applications[row]->deleteLater();
|
|
||||||
m_applications.removeAt(row);
|
|
||||||
m_folders.removeAt(row); // maintain indicies
|
|
||||||
endRemoveRows();
|
|
||||||
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PinnedModel::addFolder(QString name, int row)
|
void PinnedModel::addFolder(QString name, int row)
|
||||||
{
|
{
|
||||||
if (row < 0 || row > m_applications.size()) {
|
if (row < 0 || row > m_applications.size()) {
|
||||||
|
|
@ -92,13 +79,19 @@ void PinnedModel::addFolder(QString name, int row)
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedModel::removeFolder(int row)
|
void PinnedModel::removeEntry(int row)
|
||||||
{
|
{
|
||||||
if (row < 0 || row >= m_applications.size()) {
|
if (row < 0 || row >= m_applications.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), row, row);
|
beginRemoveRows(QModelIndex(), row, row);
|
||||||
|
if (m_folders[row]) {
|
||||||
|
m_folders[row]->deleteLater();
|
||||||
|
}
|
||||||
|
if (m_applications[row]) {
|
||||||
|
m_applications[row]->deleteLater();
|
||||||
|
}
|
||||||
m_applications.removeAt(row);
|
m_applications.removeAt(row);
|
||||||
m_folders.removeAt(row);
|
m_folders.removeAt(row);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
|
|
@ -140,6 +133,51 @@ void PinnedModel::moveEntry(int fromRow, int toRow)
|
||||||
m_applet->config().sync();
|
m_applet->config().sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PinnedModel::createFolderFromApps(int sourceAppRow, int draggedAppRow)
|
||||||
|
{
|
||||||
|
if (sourceAppRow < 0 || sourceAppRow >= m_applications.size() || draggedAppRow < 0 || draggedAppRow >= m_applications.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceAppRow == draggedAppRow || !m_applications[sourceAppRow] || !m_applications[draggedAppRow]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace source app with folder containing both apps
|
||||||
|
ApplicationFolder *folder = new ApplicationFolder(this, i18nc("Default application folder name.", "Folder"));
|
||||||
|
connect(folder, &ApplicationFolder::saveRequested, this, &PinnedModel::save);
|
||||||
|
|
||||||
|
folder->addApp(m_applications[sourceAppRow]->storageId(), 0);
|
||||||
|
folder->addApp(m_applications[draggedAppRow]->storageId(), 0);
|
||||||
|
|
||||||
|
m_applications[sourceAppRow]->deleteLater();
|
||||||
|
m_applications[sourceAppRow] = nullptr;
|
||||||
|
m_folders[sourceAppRow] = folder;
|
||||||
|
|
||||||
|
Q_EMIT dataChanged(index(sourceAppRow, 0), index(sourceAppRow, 0), {IsFolderRole, ApplicationRole, FolderRole});
|
||||||
|
save();
|
||||||
|
|
||||||
|
// remove dragged app after
|
||||||
|
removeEntry(draggedAppRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedModel::addAppToFolder(int appRow, int folderRow)
|
||||||
|
{
|
||||||
|
if (appRow < 0 || appRow >= m_applications.size() || folderRow < 0 || folderRow >= m_applications.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_applications[appRow] || !m_folders[folderRow]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationFolder *folder = m_folders[folderRow];
|
||||||
|
Application *app = m_applications[appRow];
|
||||||
|
folder->addApp(app->storageId(), folder->applications().count());
|
||||||
|
|
||||||
|
removeEntry(appRow);
|
||||||
|
}
|
||||||
|
|
||||||
void PinnedModel::load()
|
void PinnedModel::load()
|
||||||
{
|
{
|
||||||
if (!m_applet) {
|
if (!m_applet) {
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,13 @@ public:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
Q_INVOKABLE void addApp(const QString &storageId, int row);
|
Q_INVOKABLE void addApp(const QString &storageId, int row);
|
||||||
Q_INVOKABLE void removeApp(int row);
|
|
||||||
Q_INVOKABLE void addFolder(QString name, int row);
|
Q_INVOKABLE void addFolder(QString name, int row);
|
||||||
Q_INVOKABLE void removeFolder(int row);
|
Q_INVOKABLE void removeEntry(int row);
|
||||||
|
|
||||||
Q_INVOKABLE void moveEntry(int fromRow, int toRow);
|
Q_INVOKABLE void moveEntry(int fromRow, int toRow);
|
||||||
|
|
||||||
|
Q_INVOKABLE void createFolderFromApps(int sourceAppRow, int draggedAppRow);
|
||||||
|
Q_INVOKABLE void addAppToFolder(int appRow, int folderRow);
|
||||||
|
|
||||||
Q_INVOKABLE void load();
|
Q_INVOKABLE void load();
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue