ControlCenter: modularity!

This commit is contained in:
ItsLemmy
2025-10-13 19:18:26 -04:00
parent 02f23e5f49
commit 10090cbd30
24 changed files with 930 additions and 493 deletions
@@ -1,66 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.UPower
import qs.Commons
import qs.Services
import qs.Widgets
// Power Profiles: performance, balanced, eco
NBox {
property real spacing: 0
// Centralized service
readonly property bool hasPP: PowerProfileService.available
RowLayout {
id: powerRow
anchors.fill: parent
anchors.margins: Style.marginS
spacing: spacing
Item {
Layout.fillWidth: true
}
// Performance
NIconButton {
icon: PowerProfileService.getIcon(PowerProfile.Performance)
tooltipText: I18n.tr("tooltips.set-power-profile", {
"profile": PowerProfileService.getName(PowerProfile.Performance)
})
enabled: hasPP
opacity: enabled ? Style.opacityFull : Style.opacityMedium
colorBg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mPrimary : Color.mSurfaceVariant
colorFg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mOnPrimary : Color.mPrimary
onClicked: PowerProfileService.setProfile(PowerProfile.Performance)
}
// Balanced
NIconButton {
icon: PowerProfileService.getIcon(PowerProfile.Balanced)
tooltipText: I18n.tr("tooltips.set-power-profile", {
"profile": PowerProfileService.getName(PowerProfile.Balanced)
})
enabled: hasPP
opacity: enabled ? Style.opacityFull : Style.opacityMedium
colorBg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mPrimary : Color.mSurfaceVariant
colorFg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnPrimary : Color.mPrimary
onClicked: PowerProfileService.setProfile(PowerProfile.Balanced)
}
// Eco
NIconButton {
icon: PowerProfileService.getIcon(PowerProfile.PowerSaver)
tooltipText: I18n.tr("tooltips.set-power-profile", {
"profile": PowerProfileService.getName(PowerProfile.PowerSaver)
})
enabled: hasPP
opacity: enabled ? Style.opacityFull : Style.opacityMedium
colorBg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mPrimary : Color.mSurfaceVariant
colorFg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mOnPrimary : Color.mPrimary
onClicked: PowerProfileService.setProfile(PowerProfile.PowerSaver)
}
Item {
Layout.fillWidth: true
}
}
}
@@ -0,0 +1,84 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Modules.ControlCenter.Cards
import qs.Commons
import qs.Services
import qs.Widgets
import qs.Modules.ControlCenter.Extras
RowLayout {
Layout.fillWidth: true
spacing: Style.marginL
NBox {
Layout.fillWidth: true
Layout.preferredHeight: root.shortcutsHeight
RowLayout {
id: leftContent
anchors.fill: parent
spacing: Style.marginS
Item {
Layout.fillWidth: true
}
Repeater {
model: Settings.data.controlCenter.shortcuts.left
delegate: ControlCenterWidgetLoader {
Layout.fillWidth: false
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
"widgetId": modelData.id,
"section": "quickSettings",
"sectionWidgetIndex": index,
"sectionWidgetsCount": Settings.data.controlCenter.shortcuts.left.length
}
Layout.alignment: Qt.AlignVCenter
}
}
Item {
Layout.fillWidth: true
}
}
}
NBox {
Layout.fillWidth: true
Layout.preferredHeight: root.shortcutsHeight
RowLayout {
id: rightContent
anchors.fill: parent
spacing: Style.marginS
Item {
Layout.fillWidth: true
}
Repeater {
model: Settings.data.controlCenter.shortcuts.right
delegate: ControlCenterWidgetLoader {
Layout.fillWidth: false
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
"widgetId": modelData.id,
"section": "quickSettings",
"sectionWidgetIndex": index,
"sectionWidgetsCount": Settings.data.controlCenter.shortcuts.right.length
}
Layout.alignment: Qt.AlignVCenter
}
}
Item {
Layout.fillWidth: true
}
}
}
}
@@ -1,66 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Modules.Settings
import qs.Services
import qs.Widgets
// Utilities: record & wallpaper
NBox {
property real spacing: 0
RowLayout {
id: utilRow
anchors.fill: parent
anchors.margins: Style.marginS
spacing: spacing
Item {
Layout.fillWidth: true
}
// Screen Recorder
NIconButton {
icon: "camera-video"
enabled: ScreenRecorderService.isAvailable
tooltipText: ScreenRecorderService.isAvailable ? (ScreenRecorderService.isRecording ? I18n.tr("tooltips.stop-screen-recording") : I18n.tr("tooltips.start-screen-recording")) : I18n.tr("tooltips.screen-recorder-not-installed")
colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : Color.mSurfaceVariant
colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mPrimary
onClicked: {
if (!ScreenRecorderService.isAvailable)
return
ScreenRecorderService.toggleRecording()
// If we were not recording and we just initiated a start, close the panel
if (!ScreenRecorderService.isRecording) {
var panel = PanelService.getPanel("controlCenterPanel")
panel?.close()
}
}
}
// Idle Inhibitor
NIconButton {
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
colorBg: IdleInhibitorService.isInhibited ? Color.mPrimary : Color.mSurfaceVariant
colorFg: IdleInhibitorService.isInhibited ? Color.mOnPrimary : Color.mPrimary
onClicked: {
IdleInhibitorService.manualToggle()
}
}
// Wallpaper
NIconButton {
visible: Settings.data.wallpaper.enabled
icon: "wallpaper-selector"
tooltipText: I18n.tr("tooltips.wallpaper-selector")
onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
onRightClicked: WallpaperService.setRandomWallpaper()
}
Item {
Layout.fillWidth: true
}
}
}
+84 -44
View File
@@ -13,11 +13,33 @@ NPanel {
panelKeyboardFocus: true
preferredWidth: Math.round(460 * Style.uiScaleRatio)
preferredHeight: {
let height = profileHeight + weatherHeight + mediaSysMonHeight + utilsHeight
let count = 4
if (Settings.data.controlCenter.audioControlsEnabled) {
var height = 0
var count = 0
for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
const card = Settings.data.controlCenter.cards[i]
if (!card.enabled) {
continue
}
count++
height += audioHeight
switch (card.id) {
case "profile-card":
height += profileHeight
break
case "shortcuts-card":
height += shortcutsHeight
break
case "audio-card":
height += audioHeight
break
case "weather-card":
height += weatherHeight
break
case "media-sysmon-card":
height += mediaSysMonHeight
break
default:
break
}
}
return height + (count + 1) * Style.marginL
}
@@ -32,15 +54,14 @@ NPanel {
panelAnchorTop: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
readonly property int profileHeight: Math.round(64 * Style.uiScaleRatio)
readonly property int shortcutsHeight: Math.round(52 * Style.uiScaleRatio)
readonly property int audioHeight: Math.round(120 * Style.uiScaleRatio)
readonly property int weatherHeight: Math.round(190 * Style.uiScaleRatio)
readonly property int mediaSysMonHeight: Math.round(260 * Style.uiScaleRatio)
readonly property int audioHeight: Math.round(120 * Style.uiScaleRatio)
readonly property int utilsHeight: Math.round(52 * Style.uiScaleRatio)
panelContent: Item {
id: content
// Layout content
ColumnLayout {
id: layout
x: Style.marginL
@@ -48,50 +69,69 @@ NPanel {
width: parent.width - (Style.marginL * 2)
spacing: Style.marginL
// Profile
ProfileCard {
Layout.fillWidth: true
Layout.preferredHeight: profileHeight
}
// Utils
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: utilsHeight
spacing: Style.marginL
// Power Profiles switcher
PowerProfilesCard {
Repeater {
model: Settings.data.controlCenter.cards
Loader {
active: modelData.enabled
visible: active
Layout.fillWidth: true
Layout.fillHeight: true
spacing: Style.marginL
}
// Utilities buttons
UtilitiesCard {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: Style.marginL
Layout.preferredHeight: {
switch (modelData.id) {
case "profile-card":
return profileHeight
case "shortcuts-card":
return shortcutsHeight
case "audio-card":
return audioHeight
case "weather-card":
return weatherHeight
case "media-sysmon-card":
return mediaSysMonHeight
default:
return 0
}
}
sourceComponent: {
switch (modelData.id) {
case "profile-card":
return profileCard
case "shortcuts-card":
return shortcutsCard
case "audio-card":
return audioCard
case "weather-card":
return weatherCard
case "media-sysmon-card":
return mediaSysMonCard
}
}
}
}
}
// Audio controls
AudioCard {
visible: Settings.data.controlCenter.audioControlsEnabled
Layout.fillWidth: true
Layout.preferredHeight: audioHeight
}
Component {
id: profileCard
ProfileCard {}
}
// Weather
WeatherCard {
Layout.fillWidth: true
Layout.preferredHeight: weatherHeight
}
Component {
id: shortcutsCard
ShortcutsCard {}
}
// Media + SysMon
Component {
id: audioCard
AudioCard {}
}
Component {
id: weatherCard
WeatherCard {}
}
Component {
id: mediaSysMonCard
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: mediaSysMonHeight
spacing: Style.marginL
// Media card
+1 -1
View File
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
+1 -1
View File
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
+1 -1
View File
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
enabled: ProgramCheckerService.wlsunsetAvailable
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
icon: Settings.data.notifications.doNotDisturb ? "bell-off" : "bell"
@@ -6,7 +6,7 @@ import qs.Services
import qs.Widgets
// Performance
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
readonly property bool hasPP: PowerProfileService.available
@@ -4,18 +4,13 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
enabled: ProgramCheckerService.gpuScreenRecorderAvailable
icon: "camera-video"
hot: ScreenRecorderService.isRecording
tooltipText: I18n.tr("quickSettings.screenRecorder.tooltip.action")
// Force hover state when recording to get hover colors
property bool originalHovered: hovered
hovered: ScreenRecorderService.isRecording || originalHovered
onClicked: {
ScreenRecorderService.toggleRecording()
if (!ScreenRecorderService.isRecording) {
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
enabled: Settings.data.wallpaper.enabled
+1 -1
View File
@@ -4,7 +4,7 @@ import qs.Commons
import qs.Services
import qs.Widgets
NQuickSetting {
NIconButtonHot {
property ShellScreen screen
icon: {
+19 -4
View File
@@ -14,11 +14,13 @@ NBox {
property var widgetModel: []
property var availableWidgets: []
property bool enableMoveBetweenSections: true
property int maxWidgets: -1 // -1 means unlimited
property var widgetRegistry: null
property string settingsDialogComponent: "BarWidgetSettingsDialog.qml"
readonly property real miniButtonSize: Style.baseWidgetSize * 0.65
readonly property bool isAtMaxCapacity: maxWidgets > 0 && widgetModel.length >= maxWidgets
signal addWidget(string widgetId, string section)
signal removeWidget(string section, int index)
@@ -80,6 +82,16 @@ NBox {
Layout.alignment: Qt.AlignVCenter
}
// Widget count indicator (when max is set)
NText {
visible: root.maxWidgets > 0
text: "(" + widgetModel.length + "/" + root.maxWidgets + ")"
pointSize: Style.fontSizeS
color: root.isAtMaxCapacity ? Color.mError : Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: Style.marginXS
}
Item {
Layout.fillWidth: true
}
@@ -93,6 +105,7 @@ NBox {
onSelected: key => comboBox.currentKey = key
popupHeight: 340
minimumWidth: 200
enabled: !root.isAtMaxCapacity
Layout.alignment: Qt.AlignVCenter
@@ -114,12 +127,14 @@ NBox {
colorFg: Color.mOnPrimary
colorBgHover: Color.mSecondary
colorFgHover: Color.mOnSecondary
enabled: comboBox.currentKey !== ""
tooltipText: I18n.tr("tooltips.add-widget")
enabled: comboBox.currentKey !== "" && !root.isAtMaxCapacity
tooltipText: root.isAtMaxCapacity
? I18n.tr("tooltips.max-widgets-reached")
: I18n.tr("tooltips.add-widget")
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: Style.marginS
onClicked: {
if (comboBox.currentKey !== "") {
if (comboBox.currentKey !== "" && !root.isAtMaxCapacity) {
addWidget(comboBox.currentKey, sectionId)
comboBox.currentKey = ""
}
@@ -588,4 +603,4 @@ NBox {
}
}
}
}
}
+188 -90
View File
@@ -11,6 +11,34 @@ ColumnLayout {
id: root
spacing: Style.marginL
property list<var> cardsModel: []
property list<var> cardsDefault: [{
"id": "profile-card",
"text": "Profile",
"enabled": true,
"required": true
}, {
"id": "shortcuts-card",
"text": "Shortcuts",
"enabled": true,
"required": false
}, {
"id": "weather-card",
"text": "Weather",
"enabled": true,
"required": false
}, {
"id": "audio-card",
"text": "Audio Sliders",
"enabled": true,
"required": false
}, {
"id": "media-sysmon-card",
"text": "Media and System Monitor",
"enabled": true,
"required": false
}]
// Handler for drag start - disables panel background clicks
function handleDragStart() {
var panel = PanelService.getPanel("settingsPanel")
@@ -27,6 +55,60 @@ ColumnLayout {
}
}
function saveCards() {
var toSave = []
for (var i = 0; i < cardsModel.length; i++) {
toSave.push({
"id": cardsModel[i].id,
"enabled": cardsModel[i].enabled
})
}
Settings.data.controlCenter.cards = toSave
}
Component.onCompleted: {
// Fill out availableWidgets ListModel
availableWidgets.clear()
ControlCenterWidgetRegistry.getAvailableWidgets().forEach(entry => {
availableWidgets.append({
"key": entry,
"name": entry
})
})
// Starts empty
cardsModel = []
// Add the cards available in settings
for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
const settingCard = Settings.data.controlCenter.cards[i]
for (var j = 0; j < cardsDefault.length; j++) {
if (settingCard.id === cardsDefault[j].id) {
var card = cardsDefault[j]
card.enabled = settingCard.enabled
cardsModel.push(card)
}
}
}
// Add any missing cards from default
for (var i = 0; i < cardsDefault.length; i++) {
var found = false
for (var j = 0; j < cardsModel.length; j++) {
if (cardsModel[j].id === cardsDefault[i].id) {
found = true
break
}
}
if (!found) {
cardsModel.push(cardsDefault[i])
}
}
saveCards()
}
ColumnLayout {
spacing: Style.marginL
Layout.fillWidth: true
@@ -70,11 +152,49 @@ ColumnLayout {
}
}
NToggle {
label: I18n.tr("settings.control-center.audio-controls.label")
description: I18n.tr("settings.control-center.audio-controls.description")
checked: Settings.data.controlCenter.audioControlsEnabled
onToggled: checked => Settings.data.controlCenter.audioControlsEnabled = checked
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL
Layout.bottomMargin: Style.marginXL
}
// Widgets Management Section
ColumnLayout {
spacing: Style.marginXXS
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.control-center.cards.section.label")
description: I18n.tr("settings.control-center.cards.section.description")
}
NReorderCheckboxes {
Layout.fillWidth: true
model: cardsModel
onDragPotentialStarted: {
root.handleDragStart()
}
onDragPotentialEnded: {
root.handleDragEnd()
}
onItemToggled: function (index, enabled) {
//Logger.log("ControlCenterTab", "Item", index, "toggled to", enabled)
var newModel = cardsModel.slice()
newModel[index] = Object.assign({}, newModel[index], {
"enabled": enabled
})
cardsModel = newModel
saveCards()
}
onItemsReordered: function (fromIndex, toIndex) {
//Logger.log("ControlCenterTab", "Item moved from", fromIndex, "to", toIndex)
var newModel = cardsModel.slice()
var item = newModel.splice(fromIndex, 1)[0]
newModel.splice(toIndex, 0, item)
cardsModel = newModel
saveCards()
}
}
}
NDivider {
@@ -83,70 +203,66 @@ ColumnLayout {
Layout.bottomMargin: Style.marginXL
}
// NDivider {
// Layout.fillWidth: true
// Layout.topMargin: Style.marginXL
// Layout.bottomMargin: Style.marginXL
// }
// Widgets Management Section
ColumnLayout {
spacing: Style.marginXXS
Layout.fillWidth: true
// // Widgets Management Section
// ColumnLayout {
// spacing: Style.marginXXS
// Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.control-center.shortcuts.section.label")
description: I18n.tr("settings.control-center.shortcuts.section.description")
}
// NHeader {
// label: I18n.tr("settings.control-center.quickSettings.section.label")
// description: I18n.tr("settings.control-center.quickSettings.section.description")
// }
// Sections
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: Style.marginM
spacing: Style.marginM
// // Sections
// ColumnLayout {
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.topMargin: Style.marginM
// spacing: Style.marginM
// Left
SectionEditor {
sectionName: I18n.tr("settings.control-center.shortcuts.sectionLeft")
sectionId: "left"
settingsDialogComponent: ""
maxWidgets: 5
widgetRegistry: ControlCenterWidgetRegistry
widgetModel: Settings.data.controlCenter.shortcuts["left"]
availableWidgets: availableWidgets
enableMoveBetweenSections: false
onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
onDragPotentialStarted: root.handleDragStart()
onDragPotentialEnded: root.handleDragEnd()
}
// // Left
// SectionEditor {
// sectionName: I18n.tr("settings.control-center.quickSettings.sectionLeft")
// sectionId: "left"
// settingsDialogComponent: ""
// widgetRegistry: ControlCenterWidgetRegistry
// widgetModel: Settings.data.controlCenter.widgets["left"]
// availableWidgets: availableWidgets
// enableMoveBetweenSections: false
// onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
// onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
// onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
// onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
// onDragPotentialStarted: root.handleDragStart()
// onDragPotentialEnded: root.handleDragEnd()
// }
// Right
SectionEditor {
sectionName: I18n.tr("settings.control-center.shortcuts.sectionRight")
sectionId: "right"
settingsDialogComponent: ""
maxWidgets: 5
widgetRegistry: ControlCenterWidgetRegistry
widgetModel: Settings.data.controlCenter.shortcuts["right"]
availableWidgets: availableWidgets
enableMoveBetweenSections: false
onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
onDragPotentialStarted: root.handleDragStart()
onDragPotentialEnded: root.handleDragEnd()
}
}
}
// // Right
// SectionEditor {
// sectionName: I18n.tr("settings.control-center.quickSettings.sectionRight")
// sectionId: "right"
// settingsDialogComponent: ""
// widgetRegistry: ControlCenterWidgetRegistry
// widgetModel: Settings.data.controlCenter.widgets["right"]
// availableWidgets: availableWidgets
// enableMoveBetweenSections: false
// onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
// onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
// onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
// onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
// onDragPotentialStarted: root.handleDragStart()
// onDragPotentialEnded: root.handleDragEnd()
// }
// }
// }
// NDivider {
// Layout.fillWidth: true
// Layout.topMargin: Style.marginXL
// Layout.bottomMargin: Style.marginXL
// }
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL
Layout.bottomMargin: Style.marginXL
}
// ---------------------------------
// Signal functions
@@ -165,55 +281,37 @@ ColumnLayout {
})
}
}
Settings.data.controlCenter.widgets[section].push(newWidget)
Settings.data.controlCenter.shortcuts[section].push(newWidget)
}
function _removeWidgetFromSection(section, index) {
if (index >= 0 && index < Settings.data.controlCenter.widgets[section].length) {
var newArray = Settings.data.controlCenter.widgets[section].slice()
if (index >= 0 && index < Settings.data.controlCenter.shortcuts[section].length) {
var newArray = Settings.data.controlCenter.shortcuts[section].slice()
var removedWidgets = newArray.splice(index, 1)
Settings.data.controlCenter.widgets[section] = newArray
// Check that we still have a control center
if (removedWidgets[0].id === "ControlCenter" && BarService.lookupWidget("ControlCenter") === undefined) {
ToastService.showWarning(I18n.tr("toast.missing-control-center.label"), I18n.tr("toast.missing-control-center.description"), 12000)
}
Settings.data.controlCenter.shortcuts[section] = newArray
}
}
function _reorderWidgetInSection(section, fromIndex, toIndex) {
if (fromIndex >= 0 && fromIndex < Settings.data.controlCenter.widgets[section].length && toIndex >= 0 && toIndex < Settings.data.controlCenter.widgets[section].length) {
if (fromIndex >= 0 && fromIndex < Settings.data.controlCenter.shortcuts[section].length && toIndex >= 0 && toIndex < Settings.data.controlCenter.shortcuts[section].length) {
// Create a new array to avoid modifying the original
var newArray = Settings.data.controlCenter.widgets[section].slice()
var newArray = Settings.data.controlCenter.shortcuts[section].slice()
var item = newArray[fromIndex]
newArray.splice(fromIndex, 1)
newArray.splice(toIndex, 0, item)
Settings.data.controlCenter.widgets[section] = newArray
//Logger.log("BarTab", "Widget reordered. New array:", JSON.stringify(newArray))
Settings.data.controlCenter.shortcuts[section] = newArray
}
}
function _updateWidgetSettingsInSection(section, index, settings) {
// Update the widget settings in the Settings data
Settings.data.controlCenter.widgets[section][index] = settings
//Logger.log("BarTab", `Updated widget settings for ${settings.id} in ${section} section`)
Settings.data.controlCenter.shortcuts[section][index] = settings
}
// Base list model for all combo boxes
ListModel {
id: availableWidgets
}
Component.onCompleted: {
// Fill out availableWidgets ListModel
availableWidgets.clear()
ControlCenterWidgetRegistry.getAvailableWidgets().forEach(entry => {
availableWidgets.append({
"key": entry,
"name": entry
})
})
}
}