end of rework, uses horizontal icon buttons instead of drag handlers and vertical views
This commit is contained in:
@@ -8,10 +8,6 @@ JsonObject {
|
|||||||
id: "workspaces",
|
id: "workspaces",
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "audio",
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "media",
|
id: "media",
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -24,10 +20,6 @@ JsonObject {
|
|||||||
id: "updates",
|
id: "updates",
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "dash",
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "spacer",
|
id: "spacer",
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -48,10 +40,6 @@ JsonObject {
|
|||||||
id: "tray",
|
id: "tray",
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "upower",
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "network",
|
id: "network",
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@@ -11,129 +11,26 @@ import qs.Helpers
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var boxEntries: [[], [], []]
|
|
||||||
property bool dragActive: false
|
property bool dragActive: false
|
||||||
property real dragHeight: 0
|
property real dragHeight: 0
|
||||||
property real dragPointerStartX: 0
|
|
||||||
property real dragPointerStartY: 0
|
|
||||||
property real dragStartX: 0
|
property real dragStartX: 0
|
||||||
property real dragStartY: 0
|
property real dragStartY: 0
|
||||||
property real dragX: 0
|
property real dragX: 0
|
||||||
property real dragY: 0
|
property real dragY: 0
|
||||||
property int draggedBox: -1
|
property var draggedModelData: null
|
||||||
property int draggedIndex: -1
|
property string draggedUid: ""
|
||||||
property var draggedItemData: null
|
|
||||||
property bool dropAnimating: false
|
property bool dropAnimating: false
|
||||||
readonly property bool highlighted: SettingsHighlight.highlightedSetting === name
|
readonly property bool highlighted: SettingsHighlight.highlightedSetting === name
|
||||||
required property string name
|
required property string name
|
||||||
required property var object
|
required property var object
|
||||||
property var pendingCommitBoxes: []
|
property var pendingCommitEntries: []
|
||||||
required property string setting
|
required property string setting
|
||||||
property var spacerEntries: []
|
property int uidCounter: 0
|
||||||
|
property var visualEntries: []
|
||||||
|
|
||||||
function beginVisualDrag(wrapper, item, pointerX, pointerY) {
|
function ensureVisualEntries() {
|
||||||
const pos = item.mapToItem(root, 0, 0);
|
if (!root.dragActive && !root.dropAnimating)
|
||||||
const loc = root.locateEntry(wrapper.entry);
|
root.rebuildVisualEntries();
|
||||||
|
|
||||||
root.draggedItemData = wrapper;
|
|
||||||
|
|
||||||
if (loc) {
|
|
||||||
root.draggedBox = loc.box;
|
|
||||||
root.draggedIndex = loc.index;
|
|
||||||
} else {
|
|
||||||
root.draggedBox = -1;
|
|
||||||
root.draggedIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
root.dragHeight = item.height;
|
|
||||||
root.dragStartX = pos.x;
|
|
||||||
root.dragStartY = pos.y;
|
|
||||||
root.dragPointerStartX = pointerX;
|
|
||||||
root.dragPointerStartY = pointerY;
|
|
||||||
root.dragX = pos.x;
|
|
||||||
root.dragY = pos.y;
|
|
||||||
root.dragActive = true;
|
|
||||||
root.dropAnimating = false;
|
|
||||||
root.pendingCommitBoxes = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function cloneAndUpdateEnabled(entry, value) {
|
|
||||||
const list = root.object[root.setting].slice();
|
|
||||||
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
if (list[i] === entry) {
|
|
||||||
list[i] = {
|
|
||||||
id: list[i].id,
|
|
||||||
enabled: value
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
root.object[root.setting] = list;
|
|
||||||
Config.save();
|
|
||||||
root.rebuildBoxEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
function commitBoxEntries(boxes) {
|
|
||||||
const spacers = root.spacerEntries.length === 2 ? root.spacerEntries : (root.object[root.setting] ?? []).filter(e => root.isSpacer(e));
|
|
||||||
|
|
||||||
const next = [];
|
|
||||||
next.push(...boxes[0].map(w => w.entry));
|
|
||||||
next.push(spacers[0]);
|
|
||||||
next.push(...boxes[1].map(w => w.entry));
|
|
||||||
next.push(spacers[1]);
|
|
||||||
next.push(...boxes[2].map(w => w.entry));
|
|
||||||
|
|
||||||
root.object[root.setting] = next;
|
|
||||||
Config.save();
|
|
||||||
root.rebuildBoxEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
function endVisualDrag() {
|
|
||||||
if (!root.draggedItemData)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const boxes = root.boxEntries.map(box => box.slice());
|
|
||||||
const loc = root.locateEntry(root.draggedItemData.entry);
|
|
||||||
|
|
||||||
root.dragActive = false;
|
|
||||||
|
|
||||||
if (!loc) {
|
|
||||||
root.pendingCommitBoxes = boxes;
|
|
||||||
root.finishVisualDrag();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const view = [boxView0, boxView1, boxView2][loc.box];
|
|
||||||
const item = view ? view.itemAtIndex(loc.index) : null;
|
|
||||||
|
|
||||||
root.pendingCommitBoxes = boxes;
|
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
root.finishVisualDrag();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pos = item.mapToItem(root, 0, 0);
|
|
||||||
root.dropAnimating = true;
|
|
||||||
settleX.to = pos.x;
|
|
||||||
settleY.to = pos.y;
|
|
||||||
settleAnim.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
function finishVisualDrag() {
|
|
||||||
const boxes = root.pendingCommitBoxes.slice();
|
|
||||||
|
|
||||||
root.dragActive = false;
|
|
||||||
root.dropAnimating = false;
|
|
||||||
root.draggedItemData = null;
|
|
||||||
root.draggedBox = -1;
|
|
||||||
root.draggedIndex = -1;
|
|
||||||
root.pendingCommitBoxes = [];
|
|
||||||
root.dragHeight = 0;
|
|
||||||
|
|
||||||
root.commitBoxEntries(boxes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function iconForId(id) {
|
function iconForId(id) {
|
||||||
@@ -164,15 +61,18 @@ Item {
|
|||||||
return "schedule";
|
return "schedule";
|
||||||
case "notifBell":
|
case "notifBell":
|
||||||
return "notifications";
|
return "notifications";
|
||||||
case "hyprsunset":
|
|
||||||
return "wb_twilight";
|
|
||||||
default:
|
default:
|
||||||
return "drag_indicator";
|
return "drag_indicator";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSpacer(entry) {
|
function indexForUid(uid) {
|
||||||
return entry && entry.id === "spacer";
|
for (let i = 0; i < root.visualEntries.length; i++) {
|
||||||
|
if (root.visualEntries[i].uid === uid)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function labelForId(id) {
|
function labelForId(id) {
|
||||||
@@ -203,103 +103,53 @@ Item {
|
|||||||
return qsTr("Clock");
|
return qsTr("Clock");
|
||||||
case "notifBell":
|
case "notifBell":
|
||||||
return qsTr("Notification bell");
|
return qsTr("Notification bell");
|
||||||
case "hyprsunset":
|
|
||||||
return qsTr("Sunset");
|
|
||||||
default:
|
default:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function locateEntry(entry) {
|
function rebuildVisualEntries() {
|
||||||
for (let b = 0; b < root.boxEntries.length; b++) {
|
const entries = root.object[root.setting] ?? [];
|
||||||
for (let i = 0; i < root.boxEntries[b].length; i++) {
|
const next = [];
|
||||||
if (root.boxEntries[b][i].entry === entry) {
|
|
||||||
return {
|
|
||||||
box: b,
|
|
||||||
index: i
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
for (let i = 0; i < entries.length; i++) {
|
||||||
}
|
const entry = entries[i];
|
||||||
|
let existing = null;
|
||||||
|
|
||||||
function moveArrayItem(list, from, to) {
|
for (let j = 0; j < root.visualEntries.length; j++) {
|
||||||
const next = list.slice();
|
if (root.visualEntries[j].entry === entry) {
|
||||||
const item = next.splice(from, 1)[0];
|
existing = root.visualEntries[j];
|
||||||
next.splice(to, 0, item);
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
function previewMoveToBox(sourceEntry, targetBox, targetIndex, before) {
|
|
||||||
const current = root.boxEntries.map(box => box.slice());
|
|
||||||
const loc = root.locateEntry(sourceEntry);
|
|
||||||
|
|
||||||
if (!loc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const moved = current[loc.box].splice(loc.index, 1)[0];
|
|
||||||
|
|
||||||
let insertAt = targetIndex + (before ? 0 : 1);
|
|
||||||
|
|
||||||
if (loc.box === targetBox && insertAt > loc.index)
|
|
||||||
insertAt -= 1;
|
|
||||||
|
|
||||||
insertAt = Math.max(0, Math.min(current[targetBox].length, insertAt));
|
|
||||||
current[targetBox].splice(insertAt, 0, moved);
|
|
||||||
|
|
||||||
root.boxEntries = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
function rebuildBoxEntries() {
|
|
||||||
const list = root.object[root.setting] ?? [];
|
|
||||||
const next = [[], [], []];
|
|
||||||
const spacers = [];
|
|
||||||
let box = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
const entry = list[i];
|
|
||||||
|
|
||||||
if (root.isSpacer(entry)) {
|
|
||||||
spacers.push(entry);
|
|
||||||
box = Math.min(2, box + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
next[box].push({
|
|
||||||
entry: entry
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
root.spacerEntries = spacers;
|
|
||||||
root.boxEntries = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateEntry(entry, value) {
|
|
||||||
const list = root.object[root.setting].slice();
|
|
||||||
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
if (list[i] === entry) {
|
|
||||||
list[i] = {
|
|
||||||
id: list[i].id,
|
|
||||||
enabled: value
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existing)
|
||||||
|
next.push(existing);
|
||||||
|
else
|
||||||
|
next.push({
|
||||||
|
uid: `entry-${root.uidCounter++}`,
|
||||||
|
entry
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root.visualEntries = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateEntry(index, value) {
|
||||||
|
const list = [...root.object[root.setting]];
|
||||||
|
const entry = list[index];
|
||||||
|
entry.enabled = value;
|
||||||
|
list[index] = entry;
|
||||||
root.object[root.setting] = list;
|
root.object[root.setting] = list;
|
||||||
Config.save();
|
Config.save();
|
||||||
root.rebuildBoxEntries();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: mainLayout.implicitHeight
|
implicitHeight: layout.implicitHeight
|
||||||
|
|
||||||
Component.onCompleted: root.rebuildBoxEntries()
|
Component.onCompleted: root.rebuildVisualEntries()
|
||||||
|
|
||||||
Rectangle {
|
CustomRect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: -Appearance.padding.smaller
|
anchors.margins: -Appearance.padding.smaller
|
||||||
color: DynamicColors.palette.m3primaryContainer
|
color: DynamicColors.palette.m3primaryContainer
|
||||||
@@ -314,294 +164,55 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelAnimation {
|
RowLayout {
|
||||||
id: settleAnim
|
id: layout
|
||||||
|
|
||||||
onFinished: root.finishVisualDrag()
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
id: settleX
|
|
||||||
|
|
||||||
duration: Appearance.anim.durations.normal
|
|
||||||
property: "dragX"
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
id: settleY
|
|
||||||
|
|
||||||
duration: Appearance.anim.durations.normal
|
|
||||||
property: "dragY"
|
|
||||||
target: root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: mainLayout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: Appearance.spacing.smaller
|
spacing: Appearance.spacing.smaller
|
||||||
|
|
||||||
CustomText {
|
DelegateModel {
|
||||||
Layout.fillWidth: true
|
id: visualModel
|
||||||
font.pointSize: Appearance.font.size.larger
|
|
||||||
text: root.name
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 260
|
|
||||||
color: DynamicColors.tPalette.m3surface
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: boxView0
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.small
|
|
||||||
clip: false
|
|
||||||
delegate: entryDelegate
|
delegate: entryDelegate
|
||||||
interactive: false
|
|
||||||
model: root.boxEntries[0]
|
model: ScriptModel {
|
||||||
spacing: Appearance.spacing.small
|
objectProp: "uid"
|
||||||
|
values: root.visualEntries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomRect {
|
Repeater {
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 260
|
|
||||||
color: DynamicColors.tPalette.m3surface
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: boxView1
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.small
|
|
||||||
clip: false
|
|
||||||
delegate: entryDelegate
|
delegate: entryDelegate
|
||||||
interactive: false
|
model: visualModel
|
||||||
model: root.boxEntries[1]
|
|
||||||
spacing: Appearance.spacing.small
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 260
|
|
||||||
color: DynamicColors.tPalette.m3surface
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: boxView2
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.small
|
|
||||||
clip: false
|
|
||||||
delegate: entryDelegate
|
|
||||||
interactive: false
|
|
||||||
model: root.boxEntries[2]
|
|
||||||
spacing: Appearance.spacing.small
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: root.dragActive || root.dropAnimating
|
|
||||||
asynchronous: false
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
property real listWidth: boxView0.width
|
|
||||||
|
|
||||||
Drag.active: root.dragActive
|
|
||||||
Drag.hotSpot.x: width / 2
|
|
||||||
Drag.hotSpot.y: height / 2
|
|
||||||
height: proxyRect.implicitHeight
|
|
||||||
width: listWidth
|
|
||||||
x: root.dragX
|
|
||||||
y: root.dragY
|
|
||||||
z: 100
|
|
||||||
|
|
||||||
Drag.source: QtObject {
|
|
||||||
property var entry: root.draggedItemData ? root.draggedItemData.entry : null
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: proxyRect
|
|
||||||
|
|
||||||
color: DynamicColors.tPalette.m3surface
|
|
||||||
implicitHeight: proxyRow.implicitHeight + Appearance.padding.small * 2
|
|
||||||
implicitWidth: parent.width
|
|
||||||
opacity: 0.95
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: proxyRow
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.small
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
color: Qt.alpha(DynamicColors.palette.m3onSurface, 0.12)
|
|
||||||
implicitHeight: 32
|
|
||||||
implicitWidth: implicitHeight
|
|
||||||
radius: Appearance.rounding.small
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: DynamicColors.palette.m3onSurfaceVariant
|
|
||||||
text: "drag_indicator"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
color: DynamicColors.palette.m3onSurfaceVariant
|
|
||||||
text: root.iconForId(root.draggedItemData?.entry?.id ?? "")
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pointSize: Appearance.font.size.larger
|
|
||||||
text: root.labelForId(root.draggedItemData?.entry?.id ?? "")
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomSwitch {
|
|
||||||
checked: root.draggedItemData?.entry?.enabled ?? true
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: entryDelegate
|
id: entryDelegate
|
||||||
|
|
||||||
DropArea {
|
IconButton {
|
||||||
id: slot
|
|
||||||
|
|
||||||
readonly property int boxIndex: ListView.view === boxView0 ? 0 : ListView.view === boxView1 ? 1 : 2
|
|
||||||
readonly property var entryData: modelData.entry
|
|
||||||
required property int index
|
required property int index
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
function previewReorder(drag) {
|
|
||||||
const source = drag.source;
|
|
||||||
if (!source || !source.entry || source.entry === slot.entryData)
|
|
||||||
return;
|
|
||||||
|
|
||||||
root.previewMoveToBox(source.entry, slot.boxIndex, slot.index, drag.y < height / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
height: entryRow.implicitHeight
|
|
||||||
implicitHeight: entryRow.implicitHeight
|
|
||||||
implicitWidth: ListView.view ? ListView.view.width : 0
|
|
||||||
width: ListView.view ? ListView.view.width : 0
|
|
||||||
|
|
||||||
onEntered: drag => previewReorder(drag)
|
|
||||||
onPositionChanged: drag => previewReorder(drag)
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: entryRow
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
color: DynamicColors.tPalette.m3surface
|
|
||||||
implicitHeight: entryLayout.implicitHeight + Appearance.padding.small * 2
|
|
||||||
opacity: root.draggedItemData?.entry === slot.entryData ? 0 : 1
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: entryLayout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.padding.small
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: handle
|
|
||||||
|
|
||||||
color: Qt.alpha(DynamicColors.palette.m3onSurface, handleMouse.pressed ? 0.12 : handleMouse.containsMouse ? 0.09 : 0.06)
|
|
||||||
implicitHeight: 32
|
|
||||||
implicitWidth: implicitHeight
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
CAnim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: DynamicColors.palette.m3onSurfaceVariant
|
|
||||||
text: "drag_indicator"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: handleMouse
|
|
||||||
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: pressed ? Qt.ClosedHandCursor : containsMouse ? Qt.OpenHandCursor : Qt.ArrowCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
preventStealing: true
|
|
||||||
|
|
||||||
onCanceled: {
|
|
||||||
if (root.draggedItemData && root.draggedItemData.entry === slot.entryData)
|
|
||||||
root.endVisualDrag();
|
|
||||||
}
|
|
||||||
onPositionChanged: mouse => {
|
|
||||||
if (!pressed || !root.dragActive || !root.draggedItemData || root.draggedItemData.entry !== slot.entryData)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const pointer = handle.mapToItem(root, mouse.x, mouse.y);
|
|
||||||
const offsetX = root.dragPointerStartX - root.dragStartX;
|
|
||||||
const offsetY = root.dragPointerStartY - root.dragStartY;
|
|
||||||
|
|
||||||
root.dragX = pointer.x - offsetX;
|
|
||||||
root.dragY = pointer.y - offsetY;
|
|
||||||
}
|
|
||||||
onPressed: mouse => {
|
|
||||||
const pointer = handle.mapToItem(root, mouse.x, mouse.y);
|
|
||||||
root.beginVisualDrag(slot.modelData, entryRow, pointer.x, pointer.y);
|
|
||||||
}
|
|
||||||
onReleased: {
|
|
||||||
if (root.draggedItemData && root.draggedItemData.entry === slot.entryData)
|
|
||||||
root.endVisualDrag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
color: DynamicColors.palette.m3onSurfaceVariant
|
|
||||||
text: root.iconForId(slot.entryData.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
font.pointSize: Appearance.font.size.larger
|
Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? 18 : internalChecked ? 7 : 0)
|
||||||
text: root.labelForId(slot.entryData.id)
|
checked: modelData.entry.enabled ?? true
|
||||||
|
icon: root.iconForId(modelData.entry.id)
|
||||||
|
inactiveColour: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2)
|
||||||
|
radius: stateLayer.pressed ? 6 / 2 : internalChecked ? 6 : 8
|
||||||
|
radiusAnim.duration: MaterialEasing.expressiveEffectsTime
|
||||||
|
radiusAnim.easing.bezierCurve: MaterialEasing.expressiveEffects
|
||||||
|
toggle: true
|
||||||
|
visible: !["spacer", "upower", "dash", "audio"].some(prefix => modelData.entry.id.startsWith(prefix))
|
||||||
|
|
||||||
|
Behavior on Layout.preferredWidth {
|
||||||
|
Anim {
|
||||||
|
duration: MaterialEasing.expressiveEffectsTime
|
||||||
|
easing.bezierCurve: MaterialEasing.expressiveEffects
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomSwitch {
|
onClicked: root.updateEntry(index, internalChecked)
|
||||||
Layout.rightMargin: Appearance.padding.small
|
|
||||||
checked: slot.entryData.enabled ?? true
|
|
||||||
|
|
||||||
onToggled: root.cloneAndUpdateEnabled(slot.entryData, checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user