Custom buttons: WIP implementing custom properties
This commit is contained in:
parent
3ba6899e69
commit
7f34ca4122
7 changed files with 154 additions and 33 deletions
|
|
@ -100,6 +100,31 @@ Singleton {
|
||||||
Logger.log("Settings", "Settings loaded successfully")
|
Logger.log("Settings", "Settings loaded successfully")
|
||||||
isLoaded = true
|
isLoaded = true
|
||||||
|
|
||||||
|
for (var i = 0; i < adapter.bar.widgets.left.length; i++) {
|
||||||
|
var obj = adapter.bar.widgets.left[i]
|
||||||
|
if (typeof obj === "string") {
|
||||||
|
adapter.bar.widgets.left[i] = {
|
||||||
|
"id": obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < adapter.bar.widgets.center.length; i++) {
|
||||||
|
var obj = adapter.bar.widgets.center[i]
|
||||||
|
if (typeof obj === "string") {
|
||||||
|
adapter.bar.widgets.center[i] = {
|
||||||
|
"id": obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < adapter.bar.widgets.right.length; i++) {
|
||||||
|
var obj = adapter.bar.widgets.right[i]
|
||||||
|
if (typeof obj === "string") {
|
||||||
|
adapter.bar.widgets.right[i] = {
|
||||||
|
"id": obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Emit the signal
|
// Emit the signal
|
||||||
root.settingsLoaded()
|
root.settingsLoaded()
|
||||||
|
|
||||||
|
|
@ -126,6 +151,8 @@ Singleton {
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: adapter
|
id: adapter
|
||||||
|
|
||||||
|
property int settingsVersion: 1
|
||||||
|
|
||||||
// bar
|
// bar
|
||||||
property JsonObject bar: JsonObject {
|
property JsonObject bar: JsonObject {
|
||||||
property string position: "top" // Possible values: "top", "bottom"
|
property string position: "top" // Possible values: "top", "bottom"
|
||||||
|
|
@ -140,9 +167,39 @@ Singleton {
|
||||||
// Widget configuration for modular bar system
|
// Widget configuration for modular bar system
|
||||||
property JsonObject widgets
|
property JsonObject widgets
|
||||||
widgets: JsonObject {
|
widgets: JsonObject {
|
||||||
property list<string> left: ["SystemMonitor", "ActiveWindow", "MediaMini"]
|
property list<var> left: [{
|
||||||
property list<string> center: ["Workspace"]
|
"id": "SystemMonitor"
|
||||||
property list<string> right: ["ScreenRecorderIndicator", "Tray", "NotificationHistory", "WiFi", "Bluetooth", "Battery", "Volume", "Brightness", "NightLight", "Clock", "SidePanelToggle"]
|
}, {
|
||||||
|
"id": "ActiveWindow"
|
||||||
|
}, {
|
||||||
|
"id": "MediaMini"
|
||||||
|
}]
|
||||||
|
property list<var> center: [{
|
||||||
|
"id": "Workspace"
|
||||||
|
}]
|
||||||
|
property list<var> right: [{
|
||||||
|
"id": "ScreenRecorderIndicator"
|
||||||
|
}, {
|
||||||
|
"id": "Tray"
|
||||||
|
}, {
|
||||||
|
"id": "NotificationHistory"
|
||||||
|
}, {
|
||||||
|
"id": "WiFi"
|
||||||
|
}, {
|
||||||
|
"id": "Bluetooth"
|
||||||
|
}, {
|
||||||
|
"id": "Battery"
|
||||||
|
}, {
|
||||||
|
"id": "Volume"
|
||||||
|
}, {
|
||||||
|
"id": "Brightness"
|
||||||
|
}, {
|
||||||
|
"id": "NightLight"
|
||||||
|
}, {
|
||||||
|
"id": "Clock"
|
||||||
|
}, {
|
||||||
|
"id": "SidePanelToggle"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ Variants {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Settings.data.bar.widgets.left
|
model: Settings.data.bar.widgets.left
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
widgetName: modelData
|
widgetId: modelData.id
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": root.modelData || null,
|
"screen": root.modelData || null,
|
||||||
"scaling": ScalingService.getScreenScale(screen),
|
"scaling": ScalingService.getScreenScale(screen),
|
||||||
|
|
@ -100,8 +100,7 @@ Variants {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Settings.data.bar.widgets.center
|
model: Settings.data.bar.widgets.center
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
|
widgetId: modelData.id
|
||||||
widgetName: modelData
|
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": root.modelData || null,
|
"screen": root.modelData || null,
|
||||||
"scaling": ScalingService.getScreenScale(screen),
|
"scaling": ScalingService.getScreenScale(screen),
|
||||||
|
|
@ -129,7 +128,7 @@ Variants {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Settings.data.bar.widgets.right
|
model: Settings.data.bar.widgets.right
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
widgetName: modelData
|
widgetId: modelData.id
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": root.modelData || null,
|
"screen": root.modelData || null,
|
||||||
"scaling": ScalingService.getScreenScale(screen),
|
"scaling": ScalingService.getScreenScale(screen),
|
||||||
|
|
|
||||||
26
Modules/Bar/Widgets/CustomButton.qml
Normal file
26
Modules/Bar/Widgets/CustomButton.qml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import Quickshell
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Widgets
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
NIconButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property ShellScreen screen
|
||||||
|
property real scaling: 1.0
|
||||||
|
property bool allowUserSettings: true
|
||||||
|
|
||||||
|
icon: "favorite"
|
||||||
|
tooltipText: "Hello world"
|
||||||
|
sizeRatio: 0.8
|
||||||
|
|
||||||
|
colorBg: Color.mSurfaceVariant
|
||||||
|
colorFg: Color.mOnSurface
|
||||||
|
colorBorder: Color.transparent
|
||||||
|
colorBorderHover: Color.transparent
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ ColumnLayout {
|
||||||
sectionId: "left"
|
sectionId: "left"
|
||||||
widgetModel: Settings.data.bar.widgets.left
|
widgetModel: Settings.data.bar.widgets.left
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetId, section) => addWidgetToSection(widgetId, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +173,7 @@ ColumnLayout {
|
||||||
sectionId: "center"
|
sectionId: "center"
|
||||||
widgetModel: Settings.data.bar.widgets.center
|
widgetModel: Settings.data.bar.widgets.center
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetId, section) => addWidgetToSection(widgetId, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ ColumnLayout {
|
||||||
sectionId: "right"
|
sectionId: "right"
|
||||||
widgetModel: Settings.data.bar.widgets.right
|
widgetModel: Settings.data.bar.widgets.right
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetId, section) => addWidgetToSection(widgetId, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
@ -198,14 +198,16 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
function addWidgetToSection(widgetName, section) {
|
function addWidgetToSection(widgetId, section) {
|
||||||
//Logger.log("BarTab", "Adding widget", widgetName, "to section", section)
|
//Logger.log("BarTab", "Adding widget", widgetId, "to section", section)
|
||||||
var sectionArray = Settings.data.bar.widgets[section]
|
var sectionArray = Settings.data.bar.widgets[section]
|
||||||
|
|
||||||
if (sectionArray) {
|
if (sectionArray) {
|
||||||
// Create a new array to avoid modifying the original
|
// Create a new array to avoid modifying the original
|
||||||
var newArray = sectionArray.slice()
|
var newArray = sectionArray.slice()
|
||||||
newArray.push(widgetName)
|
newArray.push({
|
||||||
|
"id": widgetId
|
||||||
|
})
|
||||||
//Logger.log("BarTab", "Widget added. New array:", JSON.stringify(newArray))
|
//Logger.log("BarTab", "Widget added. New array:", JSON.stringify(newArray))
|
||||||
|
|
||||||
// Assign the new array
|
// Assign the new array
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ Singleton {
|
||||||
"Bluetooth": bluetoothComponent,
|
"Bluetooth": bluetoothComponent,
|
||||||
"Brightness": brightnessComponent,
|
"Brightness": brightnessComponent,
|
||||||
"Clock": clockComponent,
|
"Clock": clockComponent,
|
||||||
|
"CustomButton": customButtonComponent,
|
||||||
"DarkModeToggle": darkModeToggle,
|
"DarkModeToggle": darkModeToggle,
|
||||||
"KeyboardLayout": keyboardLayoutComponent,
|
"KeyboardLayout": keyboardLayoutComponent,
|
||||||
"MediaMini": mediaMiniComponent,
|
"MediaMini": mediaMiniComponent,
|
||||||
|
|
@ -33,6 +34,15 @@ Singleton {
|
||||||
"Workspace": workspaceComponent
|
"Workspace": workspaceComponent
|
||||||
})
|
})
|
||||||
|
|
||||||
|
property var widgetMetadata: ({
|
||||||
|
"CustomButton": {
|
||||||
|
allowUserSettings: true,
|
||||||
|
icon: "favorite",
|
||||||
|
execute: ""
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// Component definitions - these are loaded once at startup
|
// Component definitions - these are loaded once at startup
|
||||||
property Component activeWindowComponent: Component {
|
property Component activeWindowComponent: Component {
|
||||||
ActiveWindow {}
|
ActiveWindow {}
|
||||||
|
|
@ -52,6 +62,9 @@ Singleton {
|
||||||
property Component clockComponent: Component {
|
property Component clockComponent: Component {
|
||||||
Clock {}
|
Clock {}
|
||||||
}
|
}
|
||||||
|
property Component customButtonComponent: Component {
|
||||||
|
CustomButton {}
|
||||||
|
}
|
||||||
property Component darkModeToggle: Component {
|
property Component darkModeToggle: Component {
|
||||||
DarkModeToggle {}
|
DarkModeToggle {}
|
||||||
}
|
}
|
||||||
|
|
@ -100,20 +113,25 @@ Singleton {
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
// Helper function to get widget component by name
|
// Helper function to get widget component by name
|
||||||
function getWidget(name) {
|
function getWidget(id) {
|
||||||
return widgets[name] || null
|
return widgets[id] || null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to check if widget exists
|
// Helper function to check if widget exists
|
||||||
function hasWidget(name) {
|
function hasWidget(id) {
|
||||||
return name in widgets
|
return id in widgets
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of available widget names
|
// Get list of available widget id
|
||||||
function getAvailableWidgets() {
|
function getAvailableWidgets() {
|
||||||
return Object.keys(widgets)
|
return Object.keys(widgets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to check if widget has user settings
|
||||||
|
function widgetHasUserSettings(id) {
|
||||||
|
return (widgetMetadata[id] !== undefined) && (widgetMetadata[id].allowUserSettings === true)
|
||||||
|
}
|
||||||
|
|
||||||
function getNPillDirection(widget) {
|
function getNPillDirection(widget) {
|
||||||
try {
|
try {
|
||||||
if (widget.barSection === "leftSection") {
|
if (widget.barSection === "leftSection") {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Commons
|
import qs.Commons
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
NBox {
|
NBox {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -12,7 +13,7 @@ NBox {
|
||||||
property var widgetModel: []
|
property var widgetModel: []
|
||||||
property var availableWidgets: []
|
property var availableWidgets: []
|
||||||
|
|
||||||
signal addWidget(string widgetName, string section)
|
signal addWidget(string widgetId, string section)
|
||||||
signal removeWidget(string section, int index)
|
signal removeWidget(string section, int index)
|
||||||
signal reorderWidget(string section, int fromIndex, int toIndex)
|
signal reorderWidget(string section, int fromIndex, int toIndex)
|
||||||
|
|
||||||
|
|
@ -32,8 +33,8 @@ NBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate widget color from name checksum
|
// Generate widget color from name checksum
|
||||||
function getWidgetColor(name) {
|
function getWidgetColor(widgetId) {
|
||||||
const totalSum = name.split('').reduce((acc, character) => {
|
const totalSum = widgetId.split('').reduce((acc, character) => {
|
||||||
return acc + character.charCodeAt(0)
|
return acc + character.charCodeAt(0)
|
||||||
}, 0)
|
}, 0)
|
||||||
switch (totalSum % 5) {
|
switch (totalSum % 5) {
|
||||||
|
|
@ -110,17 +111,18 @@ NBox {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
flow: Flow.LeftToRight
|
flow: Flow.LeftToRight
|
||||||
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: widgetModel
|
model: widgetModel
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: widgetItem
|
id: widgetItem
|
||||||
required property int index
|
required property int index
|
||||||
required property string modelData
|
required property var modelData
|
||||||
|
|
||||||
width: widgetContent.implicitWidth + Style.marginL * scaling
|
width: widgetContent.implicitWidth + Style.marginL * scaling
|
||||||
height: 40 * scaling
|
height: 40 * scaling
|
||||||
radius: Style.radiusL * scaling
|
radius: Style.radiusL * scaling
|
||||||
color: root.getWidgetColor(modelData)
|
color: root.getWidgetColor(modelData.id)
|
||||||
border.color: Color.mOutline
|
border.color: Color.mOutline
|
||||||
border.width: Math.max(1, Style.borderS * scaling)
|
border.width: Math.max(1, Style.borderS * scaling)
|
||||||
|
|
||||||
|
|
@ -151,7 +153,7 @@ NBox {
|
||||||
spacing: Style.marginXS * scaling
|
spacing: Style.marginXS * scaling
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: modelData
|
text: modelData.id
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
color: Color.mOnPrimary
|
color: Color.mOnPrimary
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
@ -159,6 +161,23 @@ NBox {
|
||||||
Layout.preferredWidth: 80 * scaling
|
Layout.preferredWidth: 80 * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: BarWidgetRegistry.widgetHasUserSettings(modelData.id)
|
||||||
|
sourceComponent: NIconButton {
|
||||||
|
icon: "settings"
|
||||||
|
sizeRatio: 0.6
|
||||||
|
colorBorder: Color.applyOpacity(Color.mOutline, "40")
|
||||||
|
colorBg: Color.mOnSurface
|
||||||
|
colorFg: Color.mOnPrimary
|
||||||
|
colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40")
|
||||||
|
colorFgHover: Color.mOnPrimary
|
||||||
|
onClicked: {
|
||||||
|
// TODO open settings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NIconButton {
|
NIconButton {
|
||||||
icon: "close"
|
icon: "close"
|
||||||
sizeRatio: 0.6
|
sizeRatio: 0.6
|
||||||
|
|
@ -193,13 +212,13 @@ NBox {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Logger.log("NSectionEditor", `Started dragging widget: ${modelData} at index ${index}`)
|
//Logger.log("NSectionEditor", `Started dragging widget: ${modelData.id} at index ${index}`)
|
||||||
// Bring to front when starting drag
|
// Bring to front when starting drag
|
||||||
widgetItem.z = 1000
|
widgetItem.z = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
onReleased: {
|
onReleased: {
|
||||||
//Logger.log("NSectionEditor", `Released widget: ${modelData} at index ${index}`)
|
//Logger.log("NSectionEditor", `Released widget: ${modelData.id} at index ${index}`)
|
||||||
// Reset z-index when drag ends
|
// Reset z-index when drag ends
|
||||||
widgetItem.z = 0
|
widgetItem.z = 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import qs.Commons
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string widgetName: ""
|
property string widgetId: ""
|
||||||
property var widgetProps: ({})
|
property var widgetProps: ({})
|
||||||
property bool enabled: true
|
property bool enabled: true
|
||||||
|
|
||||||
|
|
@ -27,12 +27,12 @@ Item {
|
||||||
id: loader
|
id: loader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: Settings.isLoaded && enabled && widgetName !== ""
|
active: Settings.isLoaded && enabled && widgetId !== ""
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return BarWidgetRegistry.getWidget(widgetName)
|
return BarWidgetRegistry.getWidget(widgetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
|
|
@ -49,14 +49,14 @@ Item {
|
||||||
item.onLoaded()
|
item.onLoaded()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Logger.log("NWidgetLoader", "Loaded", widgetName, "on screen", item.screen.name)
|
//Logger.log("NWidgetLoader", "Loaded", widgetId, "on screen", item.screen.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
onWidgetNameChanged: {
|
onWidgetIdChanged: {
|
||||||
if (widgetName && !BarWidgetRegistry.hasWidget(widgetName)) {
|
if (widgetId && !BarWidgetRegistry.hasWidget(widgetId)) {
|
||||||
Logger.warn("WidgetLoader", "Widget not found in registry:", widgetName)
|
Logger.warn("WidgetLoader", "Widget not found in registry:", widgetId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue