fix: column index desync after reorder
This commit is contained in:
@@ -12,7 +12,7 @@ Item {
|
||||
id: root
|
||||
|
||||
readonly property real nonAnimWidth: view.implicitWidth + clipWrapper.anchors.margins * 2
|
||||
readonly property real nonAnimHeight: tabs.implicitHeight + clipWrapper.anchors.topMargin + view.implicitHeight + clipWrapper.anchors.margins * 2
|
||||
readonly property real nonAnimHeight: tabs.implicitHeight + tabs.anchors.topMargin + view.implicitHeight + clipWrapper.anchors.margins + clipWrapper.anchors.topMargin
|
||||
|
||||
required property ScreenState screenState
|
||||
|
||||
@@ -22,25 +22,25 @@ Item {
|
||||
component: dashComponent,
|
||||
iconName: "dashboard",
|
||||
text: qsTr("Dashboard"),
|
||||
enabled: true
|
||||
enabled: Config.dashboard.showDashboard
|
||||
},
|
||||
{
|
||||
component: weatherComponent,
|
||||
iconName: "cloud",
|
||||
text: qsTr("Weather"),
|
||||
enabled: true
|
||||
enabled: Config.dashboard.showWeather
|
||||
},
|
||||
{
|
||||
component: mediaComponent,
|
||||
iconName: "queue_music",
|
||||
text: qsTr("Media"),
|
||||
enabled: true
|
||||
enabled: Config.dashboard.showMedia
|
||||
},
|
||||
{
|
||||
component: procsComponent,
|
||||
iconName: "speed",
|
||||
text: qsTr("Processes"),
|
||||
enabled: true
|
||||
enabled: Config.dashboard.showProcesses
|
||||
},
|
||||
];
|
||||
return allTabs.filter(tab => tab.enabled);
|
||||
@@ -60,33 +60,34 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: clipWrapper
|
||||
anchors.fill: parent
|
||||
anchors.margins: Tokens.padding.small
|
||||
// radius: Tokens.rounding.extraLarge - anchors.margins
|
||||
Tabs {
|
||||
id: tabs
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
nonAnimWidth: view.implicitWidth
|
||||
screenState: root.screenState
|
||||
tabs: root.dashboardTabs
|
||||
anchors.topMargin: ZUtils.clamp(anchors.margins - Config.bar.border, 0, anchors.margins)
|
||||
anchors.margins: Tokens.padding.small
|
||||
}
|
||||
|
||||
Tabs {
|
||||
id: tabs
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
nonAnimWidth: view.implicitWidth
|
||||
screenState: root.screenState
|
||||
tabs: root.dashboardTabs
|
||||
}
|
||||
CustomClippingRect {
|
||||
id: clipWrapper
|
||||
anchors.top: tabs.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Tokens.spacing.small
|
||||
anchors.margins: Tokens.padding.small
|
||||
radius: Tokens.rounding.extraLarge - anchors.margins
|
||||
|
||||
Item {
|
||||
id: viewWrapper
|
||||
|
||||
anchors.top: tabs.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Tokens.spacing.small
|
||||
anchors.fill: parent
|
||||
|
||||
Flickable {
|
||||
id: view
|
||||
|
||||
@@ -67,7 +67,7 @@ GridLayout {
|
||||
Rect {
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: Config.dashboard.sizes.weatherWidth
|
||||
Layout.preferredWidth: Tokens.sizes.dashboard.weatherWidth
|
||||
Layout.row: 0
|
||||
radius: root.radius
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ Row {
|
||||
id: icon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: (Config.dashboard.sizes.infoIconSize - implicitWidth) / 2
|
||||
anchors.leftMargin: (Tokens.sizes.dashboard.infoIconSize - implicitWidth) / 2
|
||||
color: Colors.palette.m3primary
|
||||
implicitSize: Math.floor(13 * 1.34)
|
||||
source: SystemInfo.osLogo
|
||||
@@ -65,7 +65,7 @@ Row {
|
||||
anchors.verticalCenter: icon.verticalCenter
|
||||
elide: Text.ElideRight
|
||||
text: `: ${SystemInfo.osPrettyName || SystemInfo.osName}`
|
||||
width: Config.dashboard.sizes.infoWidth
|
||||
width: Tokens.sizes.dashboard.infoWidth
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ Row {
|
||||
id: icon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: (Config.dashboard.sizes.infoIconSize - implicitWidth) / 2
|
||||
anchors.leftMargin: (Tokens.sizes.dashboard.infoIconSize - implicitWidth) / 2
|
||||
color: line.colour
|
||||
fill: 1
|
||||
fontStyle: Tokens.font.icon.small
|
||||
@@ -113,7 +113,7 @@ Row {
|
||||
anchors.verticalCenter: icon.verticalCenter
|
||||
elide: Text.ElideNone
|
||||
text: `: ${line.text}`
|
||||
width: Config.dashboard.sizes.infoWidth
|
||||
width: Tokens.sizes.dashboard.infoWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import ZShell.Config
|
||||
import ZShell.Services
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
@@ -88,6 +89,18 @@ Singleton {
|
||||
}
|
||||
]
|
||||
|
||||
readonly property var desktopEntries: DesktopEntries.applications.values.map(e => ({
|
||||
icon: e.icon,
|
||||
command: e.command
|
||||
}))
|
||||
|
||||
Component.onCompleted: {
|
||||
Processes.setDesktopEntries(root.desktopEntries);
|
||||
Qt.callLater(ensurePinnedFirst);
|
||||
}
|
||||
|
||||
onDesktopEntriesChanged: Processes.setDesktopEntries(root.desktopEntries)
|
||||
|
||||
readonly property string pinnedColumnId: "command"
|
||||
|
||||
readonly property var hiddenColumns: {
|
||||
@@ -113,8 +126,6 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
Component.onCompleted: Qt.callLater(ensurePinnedFirst)
|
||||
|
||||
function defFor(id: string): var {
|
||||
for (const def of root.columnDefs)
|
||||
if (def.id === id)
|
||||
|
||||
@@ -64,109 +64,83 @@ Item {
|
||||
function onWidthChanged() {
|
||||
root.fillMissingWidths();
|
||||
}
|
||||
|
||||
function onCountChanged() {
|
||||
resizeOverlay.geometryTick++;
|
||||
root.fillMissingWidths();
|
||||
}
|
||||
|
||||
function onContentWidthChanged() {
|
||||
resizeOverlay.geometryTick++;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: columnsData
|
||||
function onValuesChanged() {
|
||||
root.fillMissingWidths();
|
||||
resizeOverlay.geometryTick++;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: Qt.callLater(fillMissingWidths)
|
||||
Component.onDestruction: Cursor.clearOverride()
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
CustomListView {
|
||||
id: columnList
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
spacing: Tokens.spacing.extraSmall / 2
|
||||
|
||||
CustomListView {
|
||||
id: columnList
|
||||
|
||||
Layout.fillWidth: true
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
spacing: parent.spacing
|
||||
implicitHeight: root.headerHeight
|
||||
|
||||
add: Transition {
|
||||
Anim {
|
||||
from: 0
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
add: Transition {
|
||||
Anim {
|
||||
from: 0
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
displaced: Transition {
|
||||
Anim {
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
Anim {
|
||||
properties: "x"
|
||||
}
|
||||
}
|
||||
displaced: Transition {
|
||||
Anim {
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
move: Transition {
|
||||
Anim {
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
Anim {
|
||||
properties: "x"
|
||||
}
|
||||
Anim {
|
||||
properties: "x"
|
||||
}
|
||||
remove: Transition {
|
||||
Anim {
|
||||
to: 0
|
||||
properties: "opacity"
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
move: Transition {
|
||||
Anim {
|
||||
properties: "opacity"
|
||||
to: 1
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
|
||||
model: DelegateModel {
|
||||
id: columnsVisual
|
||||
|
||||
delegate: ColumnHeaderCell {
|
||||
parentModel: columnsVisual
|
||||
}
|
||||
|
||||
model: ScriptModel {
|
||||
id: columnsData
|
||||
values: Config.dashboard.processColumns.values
|
||||
}
|
||||
Anim {
|
||||
properties: "x"
|
||||
}
|
||||
}
|
||||
remove: Transition {
|
||||
Anim {
|
||||
to: 0
|
||||
properties: "opacity"
|
||||
type: Anim.DefaultEffects
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
id: addColumnBtn
|
||||
model: DelegateModel {
|
||||
id: columnsVisual
|
||||
|
||||
type: IconButton.Text
|
||||
icon: "add"
|
||||
font: Tokens.font.icon.medium
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: ProcessesColumns.hiddenColumns.length > 0
|
||||
onClicked: addMenu.expanded = true
|
||||
}
|
||||
delegate: ColumnHeaderCell {
|
||||
parentModel: columnsVisual
|
||||
}
|
||||
|
||||
Variants {
|
||||
id: hiddenColumnList
|
||||
|
||||
model: ProcessesColumns.hiddenColumns
|
||||
|
||||
HiddenColumnItem {}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: addMenu
|
||||
|
||||
attachTo: addColumnBtn
|
||||
items: hiddenColumnList.instances
|
||||
onItemSelected: item => ProcessesColumns.addColumn(item.modelData.id)
|
||||
model: ScriptModel {
|
||||
id: columnsData
|
||||
values: Config.dashboard.processColumns.values
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,26 +152,9 @@ Item {
|
||||
property int geometryTick: 0
|
||||
property int activeGapIndex: -1
|
||||
|
||||
anchors.fill: rowLayout
|
||||
anchors.fill: columnList
|
||||
z: 10
|
||||
|
||||
Connections {
|
||||
target: columnsData
|
||||
function onValuesChanged() {
|
||||
resizeOverlay.geometryTick++;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: columnList
|
||||
function onCountChanged() {
|
||||
resizeOverlay.geometryTick++;
|
||||
}
|
||||
function onContentWidthChanged() {
|
||||
resizeOverlay.geometryTick++;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: Qt.callLater(() => geometryTick++)
|
||||
|
||||
Repeater {
|
||||
@@ -571,8 +528,6 @@ Item {
|
||||
const rightMid = rightItem.x + rightItem.width / 2;
|
||||
if (refX > rightMid) {
|
||||
columnsVisual.items.move(myIndex, myIndex + 1);
|
||||
resizeOverlay.geometryTick++;
|
||||
Qt.callLater(() => resizeOverlay.geometryTick++);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -583,8 +538,6 @@ Item {
|
||||
const pinnedAtZero = columnList.itemAtIndex(0)?.modelData?.id === ProcessesColumns.pinnedColumnId;
|
||||
if (refX < leftMid && !(myIndex === 1 && pinnedAtZero)) {
|
||||
columnsVisual.items.move(myIndex, myIndex - 1);
|
||||
resizeOverlay.geometryTick++;
|
||||
Qt.callLater(() => resizeOverlay.geometryTick++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import ZShell.Internal
|
||||
import ZShell.Services
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property int historyLength: 30
|
||||
readonly property CircularBuffer cpuBuffer: _cpuBuffer
|
||||
readonly property CircularBuffer memoryBuffer: _memoryBuffer
|
||||
|
||||
readonly property list<var> cpuInfo: [
|
||||
{
|
||||
label: qsTr("Usage"),
|
||||
value: `${Math.round(Cpu.percentage * 100)}%`
|
||||
},
|
||||
{
|
||||
label: qsTr("Temp"),
|
||||
value: `${Math.ceil(Cpu.temperature)}°${"C"}`
|
||||
}
|
||||
]
|
||||
|
||||
readonly property list<var> memoryInfo: [
|
||||
{
|
||||
label: qsTr("Used"),
|
||||
value: memoryUsageFormat(Memory.used, Memory.total)
|
||||
},
|
||||
{
|
||||
label: qsTr("Cached"),
|
||||
value: memoryTotalFormat(Memory.cached)
|
||||
},
|
||||
{
|
||||
label: qsTr("Writes"),
|
||||
value: memoryTotalFormat(Memory.writeTotal)
|
||||
},
|
||||
{
|
||||
label: qsTr("Reads"),
|
||||
value: memoryTotalFormat(Memory.readTotal)
|
||||
}
|
||||
]
|
||||
|
||||
function memoryTotalFormat(kib: int): string {
|
||||
const fmt = UsageFmt.formatKib(kib);
|
||||
return `${fmt.value.toFixed(1)} ${fmt.unit}`;
|
||||
}
|
||||
|
||||
function memoryUsageFormat(used: int, total: int): string {
|
||||
const fmt = UsageFmt.formatKib(used, total);
|
||||
return `${fmt.value.toFixed(1)} / ${Math.floor(fmt.total)} ${fmt.unit}`;
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onUpdateTriggered(): void {
|
||||
if (Cpu.percentage >= 0 && isFinite(Cpu.percentage))
|
||||
_cpuBuffer.push(Cpu.percentage);
|
||||
}
|
||||
|
||||
target: Cpu
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onUpdateTriggered(): void {
|
||||
if (Memory.percentage >= 0 && isFinite(Memory.percentage))
|
||||
_memoryBuffer.push(Memory.percentage);
|
||||
}
|
||||
|
||||
target: Memory
|
||||
}
|
||||
|
||||
CircularBuffer {
|
||||
id: _cpuBuffer
|
||||
|
||||
capacity: root.historyLength + 1
|
||||
smoothingRadius: 2
|
||||
}
|
||||
|
||||
CircularBuffer {
|
||||
id: _memoryBuffer
|
||||
|
||||
capacity: root.historyLength + 1
|
||||
smoothingRadius: 2
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import ZShell.Components
|
||||
import ZShell.Services
|
||||
import qs.Components
|
||||
import qs.Services
|
||||
import qs.Helpers
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -9,11 +9,6 @@ import qs.Services
|
||||
Item {
|
||||
id: root
|
||||
|
||||
readonly property var desktopEntries: DesktopEntries.applications.values.map(e => ({
|
||||
icon: e.icon,
|
||||
command: e.command
|
||||
}))
|
||||
|
||||
implicitWidth: Tokens.sizes.dashboard.processesWidth
|
||||
implicitHeight: Tokens.sizes.dashboard.processesHeight
|
||||
|
||||
@@ -21,14 +16,6 @@ Item {
|
||||
service: Processes
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: DesktopEntries.applications
|
||||
function onValuesChanged(): void {
|
||||
Processes.setDesktopEntries(root.desktopEntries);
|
||||
}
|
||||
}
|
||||
Component.onCompleted: Processes.setDesktopEntries(root.desktopEntries)
|
||||
|
||||
ProcessesHeader {
|
||||
id: header
|
||||
|
||||
|
||||
Reference in New Issue
Block a user