1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-26 21:15:18 -04:00

refactor(WidgetsTab): port updated drag-and-drop functionality & cross section target ordering

This commit is contained in:
purian23
2026-06-25 12:57:34 -04:00
parent cde0d83620
commit bcd6006e25
2 changed files with 554 additions and 58 deletions
+346 -8
View File
@@ -27,6 +27,22 @@ Item {
property bool hasMultipleBars: SettingsData.barConfigs.length > 1 property bool hasMultipleBars: SettingsData.barConfigs.length > 1
property int pluginCatalogRevision: 0 property int pluginCatalogRevision: 0
property string highlightedId: ""
property string highlightedSection: ""
// Cross-section drag coordinator state + floating proxy avatar.
property bool dragActive: false
property string dragSourceSection: ""
property string dragTargetSection: ""
property string dragId: ""
property var dragWidgetData: null
property int targetIndex: -1
property real dragRowHeight: 72
property bool proxyVisible: false
property real proxyX: 0
property real proxyY: 0
property real proxyWidth: 0
DankTooltipV2 { DankTooltipV2 {
id: sharedTooltip id: sharedTooltip
} }
@@ -276,6 +292,48 @@ Item {
return coreWidgets; return coreWidgets;
} }
focus: true
Keys.onPressed: function (event) {
var flat = flatList();
if (flat.length === 0)
return;
var ctrl = (event.modifiers & Qt.ControlModifier) !== 0;
if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
var dir = event.key === Qt.Key_Down ? 1 : -1;
if (ctrl) {
if (highlightedId !== "")
moveWithinSection(highlightedSection, highlightedId, dir);
} else {
var idx = -1;
for (var i = 0; i < flat.length; i++) {
if (flat[i].section === highlightedSection && flat[i].id === highlightedId) {
idx = i;
break;
}
}
if (idx < 0) {
var f = dir > 0 ? flat[0] : flat[flat.length - 1];
highlightedSection = f.section;
highlightedId = f.id;
} else {
idx = Math.max(0, Math.min(flat.length - 1, idx + dir));
highlightedSection = flat[idx].section;
highlightedId = flat[idx].id;
}
}
event.accepted = true;
} else if ((event.key === Qt.Key_Left || event.key === Qt.Key_Right) && ctrl) {
if (highlightedId !== "")
moveAcrossSections(highlightedSection, highlightedId, event.key === Qt.Key_Right ? 1 : -1);
event.accepted = true;
} else if (event.key === Qt.Key_Space || event.key === Qt.Key_Return) {
if (highlightedId !== "") {
toggleHighlighted();
event.accepted = true;
}
}
}
Connections { Connections {
target: PluginService target: PluginService
@@ -489,8 +547,200 @@ Item {
setWidgetsForSection(sectionId, widgets); setWidgetsForSection(sectionId, widgets);
} }
function handleItemOrderChanged(sectionId, newOrder) { function barKey(sectionId) {
setWidgetsForSection(sectionId, newOrder); return sectionId === "left" ? "leftWidgets" : sectionId === "center" ? "centerWidgets" : "rightWidgets";
}
function sectionItem(sectionId) {
return sectionId === "left" ? leftSection : sectionId === "center" ? centerSection : sectionId === "right" ? rightSection : null;
}
// Id-based reorder; rebuilds from authoritative objects so every prop (incl. hideWhenIdle) survives
function reorderSection(sectionId, orderedIds) {
var current = getWidgetsForSection(sectionId);
var byId = {};
current.forEach(w => {
var id = (typeof w === "string" ? w : w.id);
byId[id] = w;
});
var reordered = [];
orderedIds.forEach(id => {
if (byId[id] !== undefined)
reordered.push(byId[id]);
});
setWidgetsForSection(sectionId, reordered);
}
// Move a widget across sections (or within); committed as one atomic bar-config save
function moveWidget(fromSection, toSection, movedId, toIndex) {
if (fromSection === toSection) {
var arr = getWidgetsForSection(fromSection).slice();
var fi = arr.findIndex(w => (typeof w === "string" ? w : w.id) === movedId);
if (fi < 0)
return;
var m = arr.splice(fi, 1)[0];
arr.splice(Math.max(0, Math.min(toIndex, arr.length)), 0, m);
setWidgetsForSection(fromSection, arr);
return;
}
var src = getWidgetsForSection(fromSection).slice();
var fromIdx = src.findIndex(w => (typeof w === "string" ? w : w.id) === movedId);
if (fromIdx < 0)
return;
var moved = src.splice(fromIdx, 1)[0];
var dst = getWidgetsForSection(toSection).slice();
dst.splice(Math.max(0, Math.min(toIndex, dst.length)), 0, moved);
var updates = {};
updates[barKey(fromSection)] = src;
updates[barKey(toSection)] = dst;
SettingsData.updateBarConfig(selectedBarId, updates);
}
function sectionAtY(gy) {
var sections = ["left", "center", "right"];
var nearest = "";
var nearestDist = Infinity;
for (var i = 0; i < sections.length; i++) {
var it = sectionItem(sections[i]);
if (!it)
continue;
var top = it.mapToItem(widgetsTab, 0, 0).y;
var bot = top + it.height;
if (gy >= top && gy <= bot)
return sections[i];
var d = gy < top ? (top - gy) : (gy - bot);
if (d < nearestDist) {
nearestDist = d;
nearest = sections[i];
}
}
return nearest;
}
function handleDragStarted(sectionId, id, index, widgetData, localPos) {
widgetsTab.forceActiveFocus();
highlightedSection = sectionId;
highlightedId = id;
dragActive = true;
dragSourceSection = sectionId;
dragTargetSection = sectionId;
dragId = id;
dragWidgetData = widgetData;
targetIndex = -1;
var src = sectionItem(sectionId);
dragRowHeight = src ? src.rowHeight : 72;
var origin = src ? src.mapToItem(widgetsTab, 0, 0) : {
"x": 0,
"y": 0
};
proxyX = origin.x;
proxyWidth = src ? src.width : 0;
proxyVisible = false;
}
function handleDragMoved(sectionId, localPos) {
if (!dragActive)
return;
var src = sectionItem(sectionId);
if (!src)
return;
var g = src.mapToItem(widgetsTab, localPos.x, localPos.y);
var hit = sectionAtY(g.y);
if (hit === "" || hit === dragSourceSection) {
if (dragTargetSection !== dragSourceSection) {
var prev = sectionItem(dragTargetSection);
if (prev)
prev.clearGap();
dragTargetSection = dragSourceSection;
}
src.setCrossMode(false);
targetIndex = -1;
proxyVisible = false;
return;
}
if (dragTargetSection !== hit) {
if (dragTargetSection !== dragSourceSection) {
var prevSec = sectionItem(dragTargetSection);
if (prevSec)
prevSec.clearGap();
}
dragTargetSection = hit;
}
src.setCrossMode(true);
var tgt = sectionItem(hit);
targetIndex = tgt.slotIndexForGlobalY(widgetsTab, g.y);
tgt.openGapAt(targetIndex);
proxyY = g.y - dragRowHeight / 2;
proxyVisible = true;
}
function handleDragEnded(sectionId) {
var src = sectionItem(dragSourceSection);
var crossing = dragTargetSection !== "" && dragTargetSection !== dragSourceSection;
if (crossing) {
moveWidget(dragSourceSection, dragTargetSection, dragId, targetIndex);
var tgt = sectionItem(dragTargetSection);
if (tgt)
tgt.clearGap();
if (src)
src.cancelDrag();
} else if (src) {
src.commitDrag();
}
if (src)
src.setCrossMode(false);
dragActive = false;
dragSourceSection = "";
dragTargetSection = "";
dragId = "";
dragWidgetData = null;
targetIndex = -1;
proxyVisible = false;
}
function flatList() {
var out = [];
["left", "center", "right"].forEach(s => {
getWidgetsForSection(s).forEach(w => {
out.push({
"section": s,
"id": (typeof w === "string" ? w : w.id)
});
});
});
return out;
}
function moveWithinSection(sectionId, id, delta) {
var ids = getWidgetsForSection(sectionId).map(w => typeof w === "string" ? w : w.id);
var pos = ids.indexOf(id);
var next = pos + delta;
if (pos < 0 || next < 0 || next >= ids.length)
return;
ids.splice(pos, 1);
ids.splice(next, 0, id);
reorderSection(sectionId, ids);
}
function moveAcrossSections(sectionId, id, delta) {
var order = ["left", "center", "right"];
var si = order.indexOf(sectionId);
var ti = si + delta;
if (si < 0 || ti < 0 || ti >= order.length)
return;
var to = order[ti];
moveWidget(sectionId, to, id, getWidgetsForSection(to).length);
highlightedSection = to;
}
function toggleHighlighted() {
if (highlightedId === "" || highlightedSection === "")
return;
var w = getWidgetsForSection(highlightedSection).find(x => (typeof x === "string" ? x : x.id) === highlightedId);
if (w === undefined)
return;
var en = (typeof w === "string") ? true : (w.enabled !== false);
handleItemEnabledChanged(highlightedSection, highlightedId, !en);
} }
function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) { function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) {
@@ -1069,8 +1319,19 @@ Item {
onItemEnabledChanged: (sectionId, itemId, enabled) => { onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled); widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
} }
onItemOrderChanged: newOrder => { highlightedId: widgetsTab.highlightedId
widgetsTab.handleItemOrderChanged(sectionId, newOrder); highlightedSection: widgetsTab.highlightedSection
onItemOrderChanged: (sectionId, orderedIds) => {
widgetsTab.reorderSection(sectionId, orderedIds);
}
onDragStarted: (sectionId, id, index, widgetData, localPos) => {
widgetsTab.handleDragStarted(sectionId, id, index, widgetData, localPos);
}
onDragMoved: (sectionId, localPos) => {
widgetsTab.handleDragMoved(sectionId, localPos);
}
onDragEnded: sectionId => {
widgetsTab.handleDragEnded(sectionId);
} }
onAddWidget: sectionId => { onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId); showWidgetSelectionPopup(sectionId);
@@ -1145,8 +1406,19 @@ Item {
onItemEnabledChanged: (sectionId, itemId, enabled) => { onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled); widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
} }
onItemOrderChanged: newOrder => { highlightedId: widgetsTab.highlightedId
widgetsTab.handleItemOrderChanged(sectionId, newOrder); highlightedSection: widgetsTab.highlightedSection
onItemOrderChanged: (sectionId, orderedIds) => {
widgetsTab.reorderSection(sectionId, orderedIds);
}
onDragStarted: (sectionId, id, index, widgetData, localPos) => {
widgetsTab.handleDragStarted(sectionId, id, index, widgetData, localPos);
}
onDragMoved: (sectionId, localPos) => {
widgetsTab.handleDragMoved(sectionId, localPos);
}
onDragEnded: sectionId => {
widgetsTab.handleDragEnded(sectionId);
} }
onAddWidget: sectionId => { onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId); showWidgetSelectionPopup(sectionId);
@@ -1221,8 +1493,19 @@ Item {
onItemEnabledChanged: (sectionId, itemId, enabled) => { onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled); widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
} }
onItemOrderChanged: newOrder => { highlightedId: widgetsTab.highlightedId
widgetsTab.handleItemOrderChanged(sectionId, newOrder); highlightedSection: widgetsTab.highlightedSection
onItemOrderChanged: (sectionId, orderedIds) => {
widgetsTab.reorderSection(sectionId, orderedIds);
}
onDragStarted: (sectionId, id, index, widgetData, localPos) => {
widgetsTab.handleDragStarted(sectionId, id, index, widgetData, localPos);
}
onDragMoved: (sectionId, localPos) => {
widgetsTab.handleDragMoved(sectionId, localPos);
}
onDragEnded: sectionId => {
widgetsTab.handleDragEnded(sectionId);
} }
onAddWidget: sectionId => { onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId); showWidgetSelectionPopup(sectionId);
@@ -1280,4 +1563,59 @@ Item {
} }
} }
} }
// Floating drag avatar, outside the DankFlickable clip so it paints over the inter-card gap.
Item {
id: dragProxy
visible: widgetsTab.proxyVisible
x: widgetsTab.proxyX
y: widgetsTab.proxyY
width: widgetsTab.proxyWidth
height: widgetsTab.dragRowHeight
z: 9999
Rectangle {
anchors.fill: parent
anchors.margins: 2
radius: Theme.cornerRadius + 6
color: Theme.secondaryContainer
border.color: Theme.primary
border.width: 2
scale: 1.02
opacity: 0.95
DankIcon {
name: "drag_indicator"
size: Theme.iconSize - 4
color: Theme.primary
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM + 8
anchors.verticalCenter: parent.verticalCenter
}
DankIcon {
id: proxyIcon
name: (widgetsTab.dragWidgetData && widgetsTab.dragWidgetData.icon) ? widgetsTab.dragWidgetData.icon : "widgets"
size: Theme.iconSize
color: Theme.primary
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM * 2 + 40
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: (widgetsTab.dragWidgetData && widgetsTab.dragWidgetData.text) ? widgetsTab.dragWidgetData.text : ""
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
elide: Text.ElideRight
anchors.left: proxyIcon.right
anchors.leftMargin: Theme.spacingM
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
}
}
}
} }
+208 -50
View File
@@ -19,7 +19,7 @@ Column {
} }
signal itemEnabledChanged(string sectionId, string itemId, bool enabled) signal itemEnabledChanged(string sectionId, string itemId, bool enabled)
signal itemOrderChanged(var newOrder) signal itemOrderChanged(string sectionId, var orderedIds)
signal addWidget(string sectionId) signal addWidget(string sectionId)
signal removeWidget(string sectionId, int widgetIndex) signal removeWidget(string sectionId, int widgetIndex)
signal spacerSizeChanged(string sectionId, int widgetIndex, int newSize) signal spacerSizeChanged(string sectionId, int widgetIndex, int newSize)
@@ -38,19 +38,121 @@ Column {
signal overflowSettingChanged(string sectionId, int widgetIndex, string settingName, var value) signal overflowSettingChanged(string sectionId, int widgetIndex, string settingName, var value)
signal hideWhenIdleChanged(string sectionId, int widgetIndex, bool enabled) signal hideWhenIdleChanged(string sectionId, int widgetIndex, bool enabled)
function cloneWidgetData(widget) { // Cross-section drag coordination with WidgetsTab (positions are section-local)
var result = { signal dragStarted(string sectionId, string id, int index, var widgetData, var localPos)
"id": widget.id, signal dragMoved(string sectionId, var localPos)
"enabled": widget.enabled signal dragEnded(string sectionId)
};
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowSize", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "keyboardLayoutNameShowIcon", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showBatteryPercent", "showBatteryPercentOnlyOnBattery", "showBatteryTime", "showBatteryTimeOnlyOnBattery", "showPrinterIcon", "showScreenSharingIcon", "showIdleInhibitorIcon", "showDoNotDisturbIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge", "trayUseInlineExpansion", "trayPopupSingleLine", "trayAutoOverflow", "trayMaxVisibleItems"]; property string highlightedId: ""
for (var i = 0; i < keys.length; i++) { property string highlightedSection: ""
if (widget[keys[i]] !== undefined)
result[keys[i]] = widget[keys[i]]; // Absolute-Y spring drag state (mirrors DankDashTab); gapIndex is the phantom drop slot
} property var workingOrder: []
return result; property int draggingIndex: -1
property string draggingId: ""
property var dragStartOrder: []
property int gapIndex: -1
property bool crossSectionActive: false
readonly property real rowHeight: 72
readonly property real rowSpacing: Theme.spacingS
readonly property real totalHeight: {
const n = items.length;
let base = n * (rowHeight + rowSpacing);
if (gapIndex >= 0)
base += (rowHeight + rowSpacing);
return Math.max(0, base - rowSpacing);
} }
function resetWorkingOrder() {
const arr = [];
for (var i = 0; i < items.length; i++)
arr.push(i);
workingOrder = arr;
}
function slotYForIndex(i) {
var pos = workingOrder.indexOf(i);
if (pos < 0)
pos = i;
var y = pos * (rowHeight + rowSpacing);
if (gapIndex >= 0 && pos >= gapIndex)
y += (rowHeight + rowSpacing);
return y;
}
function slotIndexForY(localY) {
var idx = Math.round(localY / (rowHeight + rowSpacing));
return Math.max(0, Math.min(idx, items.length));
}
function slotIndexForGlobalY(rootItem, gy) {
var p = reorderArea.mapFromItem(rootItem, 0, gy);
return slotIndexForY(p.y);
}
function beginDrag(i) {
draggingIndex = i;
draggingId = (items[i] && items[i].id) ? items[i].id : "";
dragStartOrder = workingOrder.slice();
crossSectionActive = false;
}
function updateDragTarget(centerY) {
if (draggingIndex < 0)
return;
var pos = Math.floor(centerY / (rowHeight + rowSpacing));
pos = Math.max(0, Math.min(pos, items.length - 1));
var arr = workingOrder.slice();
var d = arr.indexOf(draggingIndex);
if (d < 0 || d === pos)
return;
arr.splice(d, 1);
arr.splice(pos, 0, draggingIndex);
workingOrder = arr;
}
function setCrossMode(active) {
if (crossSectionActive === active)
return;
crossSectionActive = active;
if (active)
workingOrder = dragStartOrder.slice();
}
function openGapAt(idx) {
gapIndex = Math.max(0, Math.min(idx, items.length));
}
function clearGap() {
gapIndex = -1;
}
function commitDrag() {
if (draggingIndex < 0)
return;
const changed = JSON.stringify(workingOrder) !== JSON.stringify(dragStartOrder);
const orderedIds = workingOrder.map(i => items[i].id);
draggingIndex = -1;
draggingId = "";
crossSectionActive = false;
gapIndex = -1;
if (changed)
itemOrderChanged(sectionId, orderedIds);
}
function cancelDrag() {
draggingIndex = -1;
draggingId = "";
crossSectionActive = false;
gapIndex = -1;
resetWorkingOrder();
}
onItemsChanged: resetWorkingOrder()
Component.onCompleted: resetWorkingOrder()
width: parent.width width: parent.width
height: implicitHeight height: implicitHeight
spacing: Theme.spacingM spacing: Theme.spacingM
@@ -74,11 +176,19 @@ Column {
} }
} }
Column { Item {
id: itemsList id: reorderArea
width: parent.width width: parent.width
spacing: Theme.spacingS height: root.totalHeight
Behavior on height {
NumberAnimation {
duration: Theme.expressiveDurations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Theme.expressiveCurves.expressiveDefaultSpatial
}
}
Repeater { Repeater {
model: root.items model: root.items
@@ -86,22 +196,75 @@ Column {
delegate: Item { delegate: Item {
id: delegateItem id: delegateItem
property bool held: dragArea.pressed readonly property int rowIndex: index
property real originalY: y readonly property bool dragging: root.draggingIndex === rowIndex
readonly property bool highlighted: root.highlightedId !== "" && root.highlightedId === modelData.id && root.highlightedSection === root.sectionId
width: itemsList.width width: reorderArea.width
height: Math.max(70, textColumn.implicitHeight + 32) height: root.rowHeight
z: held ? 2 : 1 z: dragging ? 100 : (highlighted ? 3 : 1)
opacity: (dragging && root.crossSectionActive) ? 0 : 1
Binding {
target: delegateItem
property: "y"
value: root.slotYForIndex(delegateItem.rowIndex)
when: !delegateItem.dragging
restoreMode: Binding.RestoreNone
}
onYChanged: {
if (!dragging)
return;
root.dragMoved(root.sectionId, delegateItem.mapToItem(root, delegateItem.width / 2, delegateItem.height / 2));
if (!root.crossSectionActive)
root.updateDragTarget(y + height / 2);
}
Behavior on y {
enabled: !delegateItem.dragging
NumberAnimation {
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.type: Easing.BezierSpline
easing.bezierCurve: Theme.expressiveCurves.expressiveFastSpatial
}
}
Rectangle { Rectangle {
id: itemBackground id: itemBackground
anchors.fill: parent anchors.fill: parent
anchors.margins: 2 anchors.margins: 2
radius: Theme.cornerRadius scale: delegateItem.dragging ? 1.02 : 1.0
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8) transformOrigin: Item.Center
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) radius: delegateItem.dragging ? Theme.cornerRadius + 6 : Theme.cornerRadius
border.width: 0 color: delegateItem.dragging ? Theme.secondaryContainer : Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8)
border.color: delegateItem.dragging ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: delegateItem.dragging ? 2 : 0
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on radius {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
}
}
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
}
}
DankIcon { DankIcon {
name: "drag_indicator" name: "drag_indicator"
@@ -866,41 +1029,36 @@ Column {
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: 60 anchors.right: actionButtons.left
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.SizeVerCursor cursorShape: delegateItem.dragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor
drag.target: held ? delegateItem : undefined drag.target: delegateItem
drag.axis: Drag.YAxis drag.axis: Drag.YAxis
drag.minimumY: -delegateItem.height drag.minimumY: -2000
drag.maximumY: itemsList.height drag.maximumY: 4000
drag.smoothed: false
preventStealing: true preventStealing: true
onPressed: { onPressed: {
delegateItem.z = 2; root.beginDrag(delegateItem.rowIndex);
delegateItem.originalY = delegateItem.y; root.dragStarted(root.sectionId, modelData.id, delegateItem.rowIndex, modelData, delegateItem.mapToItem(root, delegateItem.width / 2, delegateItem.height / 2));
}
onReleased: {
delegateItem.z = 1;
if (drag.active) {
var newIndex = Math.round(delegateItem.y / (delegateItem.height + itemsList.spacing));
newIndex = Math.max(0, Math.min(newIndex, root.items.length - 1));
if (newIndex !== index) {
var newItems = root.items.slice();
var draggedItem = newItems.splice(index, 1)[0];
newItems.splice(newIndex, 0, draggedItem);
root.itemOrderChanged(newItems.map(item => root.cloneWidgetData(item)));
}
}
delegateItem.x = 0;
delegateItem.y = delegateItem.originalY;
} }
onReleased: root.dragEnded(root.sectionId)
} }
}
Behavior on y { Rectangle {
enabled: !dragArea.held && !dragArea.drag.active anchors.fill: parent
anchors.margins: -2
radius: Theme.cornerRadius + 2
color: "transparent"
border.width: 2
border.color: Theme.primary
opacity: delegateItem.highlighted && !delegateItem.dragging ? 0.6 : 0
visible: opacity > 0.01
Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing
} }
} }
} }
@@ -1878,7 +2036,7 @@ Column {
setting: "showDoNotDisturbIcon" setting: "showDoNotDisturbIcon"
} }
] ]
} }
] ]
property var controlCenterGroups: defaultControlCenterGroups property var controlCenterGroups: defaultControlCenterGroups
property int draggedControlCenterGroupIndex: -1 property int draggedControlCenterGroupIndex: -1