163 lines
3.9 KiB
QML
163 lines
3.9 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import qs.Modules
|
|
import qs.Helpers
|
|
import qs.Paths
|
|
import ZShell.Services
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property int cellHeight: 110
|
|
property int cellWidth: 100
|
|
property var contextMenu: desktopMenu
|
|
property string dragLeader: ""
|
|
property string editingFilePath: ""
|
|
property real groupDragX: 0
|
|
property real groupDragY: 0
|
|
property var selectedIcons: []
|
|
property real startX: 0
|
|
property real startY: 0
|
|
|
|
function exec(filePath, isDir) {
|
|
const cmd = ["xdg-open", filePath];
|
|
Quickshell.execDetached(cmd);
|
|
}
|
|
|
|
function performMassDrop(leaderPath, targetX, targetY) {
|
|
let maxCol = Math.max(0, Math.floor(gridArea.width / cellWidth) - 1);
|
|
let maxRow = Math.max(0, Math.floor(gridArea.height / cellHeight) - 1);
|
|
|
|
let visuals = [];
|
|
for (let i = 0; i < gridArea.children.length; i++) {
|
|
let child = gridArea.children[i];
|
|
if (child.filePath && root.selectedIcons.includes(child.filePath)) {
|
|
let isLeader = (root.dragLeader === child.filePath);
|
|
let offsetX = isLeader ? child.getDragX() : root.groupDragX;
|
|
let offsetY = isLeader ? child.getDragY() : root.groupDragY;
|
|
visuals.push({
|
|
childRef: child,
|
|
absX: child.x + offsetX,
|
|
absY: child.y + offsetY
|
|
});
|
|
}
|
|
}
|
|
|
|
desktopModel.massMove(root.selectedIcons, leaderPath, targetX, targetY, maxCol, maxRow);
|
|
|
|
for (let i = 0; i < visuals.length; i++) {
|
|
visuals[i].childRef.compensateAndSnap(visuals[i].absX, visuals[i].absY);
|
|
}
|
|
|
|
root.dragLeader = "";
|
|
root.groupDragX = 0;
|
|
root.groupDragY = 0;
|
|
}
|
|
|
|
anchors.fill: parent
|
|
focus: true
|
|
|
|
Keys.onPressed: event => {
|
|
if (event.key === Qt.Key_F2 && selectedIcons.length > 0)
|
|
editingFilePath = selectedIcons[0];
|
|
}
|
|
|
|
DesktopModel {
|
|
id: desktopModel
|
|
|
|
Component.onCompleted: loadDirectory(FileUtils.trimFileProtocol(Paths.desktop))
|
|
}
|
|
|
|
Rectangle {
|
|
id: lasso
|
|
|
|
border.color: Appearance.colors.colPrimary
|
|
border.width: 1
|
|
color: DynamicColors.tPalette.m3primary
|
|
radius: Appearance.rounding.small
|
|
visible: false
|
|
z: 99
|
|
}
|
|
|
|
MouseArea {
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
anchors.fill: parent
|
|
|
|
onPositionChanged: mouse => {
|
|
if (lasso.visible) {
|
|
lasso.x = Math.min(mouse.x, root.startX);
|
|
lasso.y = Math.min(mouse.y, root.startY);
|
|
lasso.width = Math.abs(mouse.x - root.startX);
|
|
lasso.height = Math.abs(mouse.y - root.startY);
|
|
|
|
let minCol = Math.floor((lasso.x - gridArea.x) / cellWidth);
|
|
let maxCol = Math.floor((lasso.x + lasso.width - gridArea.x) / cellWidth);
|
|
let minRow = Math.floor((lasso.y - gridArea.y) / cellHeight);
|
|
let maxRow = Math.floor((lasso.y + lasso.height - gridArea.y) / cellHeight);
|
|
|
|
let newSelection = [];
|
|
for (let i = 0; i < gridArea.children.length; i++) {
|
|
let child = gridArea.children[i];
|
|
if (child.filePath !== undefined && child.gridX >= minCol && child.gridX <= maxCol && child.gridY >= minRow && child.gridY <= maxRow) {
|
|
newSelection.push(child.filePath);
|
|
}
|
|
}
|
|
root.selectedIcons = newSelection;
|
|
}
|
|
}
|
|
onPressed: mouse => {
|
|
root.editingFilePath = "";
|
|
desktopMenu.close();
|
|
|
|
if (mouse.button === Qt.RightButton) {
|
|
root.selectedIcons = [];
|
|
bgContextMenu.openAt(mouse.x, mouse.y, root.width, root.height);
|
|
} else {
|
|
bgContextMenu.close();
|
|
root.selectedIcons = [];
|
|
root.startX = mouse.x;
|
|
root.startY = mouse.y;
|
|
lasso.x = mouse.x;
|
|
lasso.y = mouse.y;
|
|
lasso.width = 0;
|
|
lasso.height = 0;
|
|
lasso.visible = true;
|
|
}
|
|
}
|
|
onReleased: {
|
|
lasso.visible = false;
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: gridArea
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: 20
|
|
anchors.topMargin: 40
|
|
visible: true
|
|
|
|
Repeater {
|
|
model: desktopModel
|
|
|
|
delegate: DesktopIconDelegate {
|
|
property int itemIndex: index
|
|
}
|
|
}
|
|
}
|
|
|
|
DesktopIconContextMenu {
|
|
id: desktopMenu
|
|
|
|
onOpenFileRequested: (path, isDir) => root.exec(path, isDir)
|
|
onRenameRequested: path => {
|
|
root.editingFilePath = path;
|
|
}
|
|
}
|
|
|
|
BackgroundContextMenu {
|
|
id: bgContextMenu
|
|
|
|
}
|
|
}
|