mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-27 06:52:50 -05:00
feat: Implement drag & drop topbar widget sections in settings
This commit is contained in:
@@ -10,6 +10,249 @@ ScrollView {
|
||||
contentHeight: column.implicitHeight + Theme.spacingXL
|
||||
clip: true
|
||||
|
||||
property var baseWidgetDefinitions: [
|
||||
{
|
||||
id: "launcherButton",
|
||||
text: "App Launcher",
|
||||
description: "Quick access to application launcher",
|
||||
icon: "apps",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "workspaceSwitcher",
|
||||
text: "Workspace Switcher",
|
||||
description: "Shows current workspace and allows switching",
|
||||
icon: "view_module",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "focusedWindow",
|
||||
text: "Focused Window",
|
||||
description: "Display currently focused application title",
|
||||
icon: "window",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "clock",
|
||||
text: "Clock",
|
||||
description: "Current time and date display",
|
||||
icon: "schedule",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "weather",
|
||||
text: "Weather Widget",
|
||||
description: "Current weather conditions and temperature",
|
||||
icon: "wb_sunny",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "music",
|
||||
text: "Media Controls",
|
||||
description: "Control currently playing media",
|
||||
icon: "music_note",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "clipboard",
|
||||
text: "Clipboard Manager",
|
||||
description: "Access clipboard history",
|
||||
icon: "content_paste",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "systemResources",
|
||||
text: "System Resources",
|
||||
description: "CPU and memory usage indicators",
|
||||
icon: "memory",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "systemTray",
|
||||
text: "System Tray",
|
||||
description: "System notification area icons",
|
||||
icon: "notifications",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "controlCenterButton",
|
||||
text: "Control Center",
|
||||
description: "Access to system controls and settings",
|
||||
icon: "settings",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "notificationButton",
|
||||
text: "Notification Center",
|
||||
description: "Access to notifications and do not disturb",
|
||||
icon: "notifications",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "battery",
|
||||
text: "Battery",
|
||||
description: "Battery level and power management",
|
||||
icon: "battery_std",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "spacer",
|
||||
text: "Spacer",
|
||||
description: "Empty space to separate widgets",
|
||||
icon: "more_horiz",
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: "separator",
|
||||
text: "Separator",
|
||||
description: "Visual divider between widgets",
|
||||
icon: "remove",
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
|
||||
// Default widget configurations for each section
|
||||
property var defaultLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||
property var defaultCenterWidgets: ["music", "clock", "weather"]
|
||||
property var defaultRightWidgets: ["clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"]
|
||||
|
||||
Component.onCompleted: {
|
||||
// Initialize sections with defaults if they're empty
|
||||
if (!Prefs.topBarLeftWidgets || Prefs.topBarLeftWidgets.length === 0) {
|
||||
Prefs.setTopBarLeftWidgets(defaultLeftWidgets)
|
||||
}
|
||||
if (!Prefs.topBarCenterWidgets || Prefs.topBarCenterWidgets.length === 0) {
|
||||
Prefs.setTopBarCenterWidgets(defaultCenterWidgets)
|
||||
}
|
||||
if (!Prefs.topBarRightWidgets || Prefs.topBarRightWidgets.length === 0) {
|
||||
Prefs.setTopBarRightWidgets(defaultRightWidgets)
|
||||
}
|
||||
}
|
||||
|
||||
function addWidgetToSection(widgetId, targetSection) {
|
||||
var leftWidgets = Prefs.topBarLeftWidgets.slice()
|
||||
var centerWidgets = Prefs.topBarCenterWidgets.slice()
|
||||
var rightWidgets = Prefs.topBarRightWidgets.slice()
|
||||
|
||||
if (targetSection === "left") {
|
||||
leftWidgets.push(widgetId)
|
||||
Prefs.setTopBarLeftWidgets(leftWidgets)
|
||||
} else if (targetSection === "center") {
|
||||
centerWidgets.push(widgetId)
|
||||
Prefs.setTopBarCenterWidgets(centerWidgets)
|
||||
} else if (targetSection === "right") {
|
||||
rightWidgets.push(widgetId)
|
||||
Prefs.setTopBarRightWidgets(rightWidgets)
|
||||
}
|
||||
}
|
||||
|
||||
function removeLastWidgetFromSection(sectionId) {
|
||||
var leftWidgets = Prefs.topBarLeftWidgets.slice()
|
||||
var centerWidgets = Prefs.topBarCenterWidgets.slice()
|
||||
var rightWidgets = Prefs.topBarRightWidgets.slice()
|
||||
|
||||
if (sectionId === "left" && leftWidgets.length > 0) {
|
||||
leftWidgets.pop()
|
||||
Prefs.setTopBarLeftWidgets(leftWidgets)
|
||||
} else if (sectionId === "center" && centerWidgets.length > 0) {
|
||||
centerWidgets.pop()
|
||||
Prefs.setTopBarCenterWidgets(centerWidgets)
|
||||
} else if (sectionId === "right" && rightWidgets.length > 0) {
|
||||
rightWidgets.pop()
|
||||
Prefs.setTopBarRightWidgets(rightWidgets)
|
||||
}
|
||||
}
|
||||
|
||||
function handleItemEnabledChanged(itemId, enabled) {
|
||||
// Update the widget's enabled state in preferences
|
||||
if (itemId === "focusedWindow") {
|
||||
Prefs.setShowFocusedWindow(enabled)
|
||||
} else if (itemId === "weather") {
|
||||
Prefs.setShowWeather(enabled)
|
||||
} else if (itemId === "music") {
|
||||
Prefs.setShowMusic(enabled)
|
||||
} else if (itemId === "clipboard") {
|
||||
Prefs.setShowClipboard(enabled)
|
||||
} else if (itemId === "systemResources") {
|
||||
Prefs.setShowSystemResources(enabled)
|
||||
} else if (itemId === "systemTray") {
|
||||
Prefs.setShowSystemTray(enabled)
|
||||
} else if (itemId === "clock") {
|
||||
Prefs.setShowClock(enabled)
|
||||
} else if (itemId === "notificationButton") {
|
||||
Prefs.setShowNotificationButton(enabled)
|
||||
} else if (itemId === "controlCenterButton") {
|
||||
Prefs.setShowControlCenterButton(enabled)
|
||||
} else if (itemId === "battery") {
|
||||
Prefs.setShowBattery(enabled)
|
||||
} else if (itemId === "launcherButton") {
|
||||
Prefs.setShowLauncherButton(enabled)
|
||||
} else if (itemId === "workspaceSwitcher") {
|
||||
Prefs.setShowWorkspaceSwitcher(enabled)
|
||||
}
|
||||
// Note: spacer and separator don't need preference handling as they're always enabled
|
||||
}
|
||||
|
||||
function handleItemOrderChanged(sectionId, newOrder) {
|
||||
if (sectionId === "left") {
|
||||
Prefs.setTopBarLeftWidgets(newOrder)
|
||||
} else if (sectionId === "center") {
|
||||
Prefs.setTopBarCenterWidgets(newOrder)
|
||||
} else if (sectionId === "right") {
|
||||
Prefs.setTopBarRightWidgets(newOrder)
|
||||
}
|
||||
}
|
||||
|
||||
function getItemsForSection(sectionId) {
|
||||
var widgets = []
|
||||
var widgetIds = []
|
||||
|
||||
if (sectionId === "left") {
|
||||
widgetIds = Prefs.topBarLeftWidgets || []
|
||||
} else if (sectionId === "center") {
|
||||
widgetIds = Prefs.topBarCenterWidgets || []
|
||||
} else if (sectionId === "right") {
|
||||
widgetIds = Prefs.topBarRightWidgets || []
|
||||
}
|
||||
|
||||
widgetIds.forEach(widgetId => {
|
||||
var widgetDef = baseWidgetDefinitions.find(w => w.id === widgetId)
|
||||
if (widgetDef) {
|
||||
var item = Object.assign({}, widgetDef)
|
||||
// Set enabled state based on preferences
|
||||
if (widgetId === "focusedWindow") {
|
||||
item.enabled = Prefs.showFocusedWindow
|
||||
} else if (widgetId === "weather") {
|
||||
item.enabled = Prefs.showWeather
|
||||
} else if (widgetId === "music") {
|
||||
item.enabled = Prefs.showMusic
|
||||
} else if (widgetId === "clipboard") {
|
||||
item.enabled = Prefs.showClipboard
|
||||
} else if (widgetId === "systemResources") {
|
||||
item.enabled = Prefs.showSystemResources
|
||||
} else if (widgetId === "systemTray") {
|
||||
item.enabled = Prefs.showSystemTray
|
||||
} else if (widgetId === "clock") {
|
||||
item.enabled = Prefs.showClock
|
||||
} else if (widgetId === "notificationButton") {
|
||||
item.enabled = Prefs.showNotificationButton
|
||||
} else if (widgetId === "controlCenterButton") {
|
||||
item.enabled = Prefs.showControlCenterButton
|
||||
} else if (widgetId === "battery") {
|
||||
item.enabled = Prefs.showBattery
|
||||
} else if (widgetId === "launcherButton") {
|
||||
item.enabled = Prefs.showLauncherButton
|
||||
} else if (widgetId === "workspaceSwitcher") {
|
||||
item.enabled = Prefs.showWorkspaceSwitcher
|
||||
}
|
||||
// spacer and separator are always enabled (no preference toggle needed)
|
||||
widgets.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
return widgets
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
|
||||
@@ -18,105 +261,213 @@ ScrollView {
|
||||
topPadding: Theme.spacingL
|
||||
bottomPadding: Theme.spacingXL
|
||||
|
||||
// Top Bar Widgets Section
|
||||
StyledRect {
|
||||
// Header section
|
||||
Row {
|
||||
width: parent.width
|
||||
height: topBarSection.implicitHeight + Theme.spacingL * 2
|
||||
radius: Theme.cornerRadiusLarge
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
border.width: 1
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Column {
|
||||
id: topBarSection
|
||||
DankIcon {
|
||||
name: "widgets"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
StyledText {
|
||||
text: "Top Bar Widget Management"
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width - 400
|
||||
height: 1
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 80
|
||||
height: 28
|
||||
radius: Theme.cornerRadius
|
||||
color: resetArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
border.width: 1
|
||||
border.color: resetArea.containsMouse ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.5)
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingM
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankIcon {
|
||||
name: "widgets"
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
name: "refresh"
|
||||
size: 14
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
|
||||
StyledText {
|
||||
text: "Top Bar Widgets"
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
text: "Reset"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "Focused Window"
|
||||
description: "Show the currently focused application in the top bar"
|
||||
checked: Prefs.showFocusedWindow
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowFocusedWindow(checked);
|
||||
|
||||
MouseArea {
|
||||
id: resetArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
// Reset all sections to defaults
|
||||
Prefs.setTopBarLeftWidgets(defaultLeftWidgets)
|
||||
Prefs.setTopBarCenterWidgets(defaultCenterWidgets)
|
||||
Prefs.setTopBarRightWidgets(defaultRightWidgets)
|
||||
|
||||
// Reset all widget enabled states to defaults (all enabled)
|
||||
Prefs.setShowFocusedWindow(true)
|
||||
Prefs.setShowWeather(true)
|
||||
Prefs.setShowMusic(true)
|
||||
Prefs.setShowClipboard(true)
|
||||
Prefs.setShowSystemResources(true)
|
||||
Prefs.setShowSystemTray(true)
|
||||
Prefs.setShowClock(true)
|
||||
Prefs.setShowNotificationButton(true)
|
||||
Prefs.setShowControlCenterButton(true)
|
||||
Prefs.setShowBattery(true)
|
||||
Prefs.setShowLauncherButton(true)
|
||||
Prefs.setShowWorkspaceSwitcher(true)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "Weather Widget"
|
||||
description: "Display weather information in the top bar"
|
||||
checked: Prefs.showWeather
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowWeather(checked);
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "Media Controls"
|
||||
description: "Show currently playing media in the top bar"
|
||||
checked: Prefs.showMusic
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowMusic(checked);
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "Clipboard Button"
|
||||
description: "Show clipboard access button in the top bar"
|
||||
checked: Prefs.showClipboard
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowClipboard(checked);
|
||||
}
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: messageText.contentHeight + Theme.spacingM * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
border.width: 1
|
||||
visible: true
|
||||
opacity: 1.0
|
||||
z: 1
|
||||
|
||||
StyledText {
|
||||
id: messageText
|
||||
anchors.centerIn: parent
|
||||
text: "Drag widgets to reorder within sections. Use + to add widgets and - to remove the last widget from each section."
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.outline
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
// Widget sections
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingL
|
||||
|
||||
// Left Section
|
||||
DankSections {
|
||||
width: parent.width
|
||||
title: "Left Section"
|
||||
titleIcon: "format_align_left"
|
||||
sectionId: "left"
|
||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||
items: widgetsTab.getItemsForSection("left")
|
||||
|
||||
onItemEnabledChanged: (itemId, enabled) => {
|
||||
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "System Resources"
|
||||
description: "Display CPU and RAM usage indicators"
|
||||
checked: Prefs.showSystemResources
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowSystemResources(checked);
|
||||
}
|
||||
onItemOrderChanged: (newOrder) => {
|
||||
widgetsTab.handleItemOrderChanged("left", newOrder)
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
width: parent.width
|
||||
text: "System Tray"
|
||||
description: "Show system tray icons in the top bar"
|
||||
checked: Prefs.showSystemTray
|
||||
onToggled: (checked) => {
|
||||
return Prefs.setShowSystemTray(checked);
|
||||
}
|
||||
onAddWidget: (sectionId) => {
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||
widgetSelectionPopup.targetSection = sectionId
|
||||
widgetSelectionPopup.safeOpen()
|
||||
}
|
||||
|
||||
onRemoveLastWidget: (sectionId) => {
|
||||
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||
}
|
||||
}
|
||||
|
||||
// Center Section
|
||||
DankSections {
|
||||
width: parent.width
|
||||
title: "Center Section"
|
||||
titleIcon: "format_align_center"
|
||||
sectionId: "center"
|
||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||
items: widgetsTab.getItemsForSection("center")
|
||||
|
||||
onItemEnabledChanged: (itemId, enabled) => {
|
||||
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||
}
|
||||
|
||||
onItemOrderChanged: (newOrder) => {
|
||||
widgetsTab.handleItemOrderChanged("center", newOrder)
|
||||
}
|
||||
|
||||
onAddWidget: (sectionId) => {
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||
widgetSelectionPopup.targetSection = sectionId
|
||||
widgetSelectionPopup.safeOpen()
|
||||
}
|
||||
|
||||
onRemoveLastWidget: (sectionId) => {
|
||||
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||
}
|
||||
}
|
||||
|
||||
// Right Section
|
||||
DankSections {
|
||||
width: parent.width
|
||||
title: "Right Section"
|
||||
titleIcon: "format_align_right"
|
||||
sectionId: "right"
|
||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||
items: widgetsTab.getItemsForSection("right")
|
||||
|
||||
onItemEnabledChanged: (itemId, enabled) => {
|
||||
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||
}
|
||||
|
||||
onItemOrderChanged: (newOrder) => {
|
||||
widgetsTab.handleItemOrderChanged("right", newOrder)
|
||||
}
|
||||
|
||||
onAddWidget: (sectionId) => {
|
||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||
widgetSelectionPopup.targetSection = sectionId
|
||||
widgetSelectionPopup.safeOpen()
|
||||
}
|
||||
|
||||
onRemoveLastWidget: (sectionId) => {
|
||||
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workspace Section
|
||||
@@ -153,7 +504,6 @@ ScrollView {
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -175,11 +525,47 @@ ScrollView {
|
||||
return Prefs.setShowWorkspacePadding(checked);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Tooltip for reset button (positioned above the button)
|
||||
Rectangle {
|
||||
width: tooltipText.contentWidth + Theme.spacingM * 2
|
||||
height: tooltipText.contentHeight + Theme.spacingS * 2
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainer
|
||||
border.color: Theme.outline
|
||||
border.width: 1
|
||||
visible: resetArea.containsMouse
|
||||
opacity: resetArea.containsMouse ? 1 : 0
|
||||
y: column.y + 48 // Position above the reset button in the header
|
||||
x: parent.width - width - Theme.spacingM
|
||||
z: 100
|
||||
|
||||
StyledText {
|
||||
id: tooltipText
|
||||
anchors.centerIn: parent
|
||||
text: "Reset widget layout to defaults"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Widget selection popup
|
||||
DankWidgetSelectionPopup {
|
||||
id: widgetSelectionPopup
|
||||
anchors.centerIn: parent
|
||||
|
||||
onWidgetSelected: (widgetId, targetSection) => {
|
||||
widgetsTab.addWidgetToSection(widgetId, targetSection)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,23 @@ PanelWindow {
|
||||
let fonts = Qt.fontFamilies();
|
||||
if (fonts.indexOf("Material Symbols Rounded") === -1)
|
||||
ToastService.showError("Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions");
|
||||
|
||||
|
||||
// Connect to the force refresh signal
|
||||
Prefs.forceTopBarLayoutRefresh.connect(function() {
|
||||
console.log("TopBar: Forcing layout refresh");
|
||||
// Force layout recalculation by toggling visibility briefly
|
||||
Qt.callLater(() => {
|
||||
leftSection.visible = false;
|
||||
centerSection.visible = false;
|
||||
rightSection.visible = false;
|
||||
Qt.callLater(() => {
|
||||
leftSection.visible = true;
|
||||
centerSection.visible = true;
|
||||
rightSection.visible = true;
|
||||
console.log("TopBar: Layout refresh completed");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -36,6 +52,8 @@ PanelWindow {
|
||||
root.backgroundTransparency = Prefs.topBarTransparency;
|
||||
}
|
||||
|
||||
// Remove old manual refresh handlers - ListModel updates are automatic
|
||||
|
||||
target: Prefs
|
||||
}
|
||||
|
||||
@@ -116,12 +134,12 @@ PanelWindow {
|
||||
// Use estimated fixed widths to break circular dependencies
|
||||
readonly property int launcherButtonWidth: 40
|
||||
readonly property int workspaceSwitcherWidth: 120 // Approximate
|
||||
readonly property int focusedAppMaxWidth: focusedApp.visible ? 456 : 0
|
||||
readonly property int focusedAppMaxWidth: 456 // Fixed width since we don't have focusedApp reference
|
||||
readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2)
|
||||
readonly property int rightSectionWidth: rightSection.width
|
||||
readonly property int clockWidth: clock.width
|
||||
readonly property int mediaMaxWidth: media.visible ? 280 : 0 // Normal max width
|
||||
readonly property int weatherWidth: weather.visible ? weather.width : 0
|
||||
readonly property int clockWidth: 120 // Approximate clock width
|
||||
readonly property int mediaMaxWidth: 280 // Normal max width
|
||||
readonly property int weatherWidth: 80 // Approximate weather width
|
||||
readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0
|
||||
readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2
|
||||
readonly property int clockRightEdge: clockLeftEdge + clockWidth
|
||||
@@ -135,6 +153,79 @@ PanelWindow {
|
||||
readonly property bool spacingTight: validLayout && (leftToMediaGap < 150 || clockToRightGap < 100)
|
||||
readonly property bool overlapping: validLayout && (leftToMediaGap < 100 || clockToRightGap < 50)
|
||||
|
||||
// Helper functions
|
||||
function getWidgetEnabled(widgetId) {
|
||||
switch (widgetId) {
|
||||
case "launcherButton": return Prefs.showLauncherButton
|
||||
case "workspaceSwitcher": return Prefs.showWorkspaceSwitcher
|
||||
case "focusedWindow": return Prefs.showFocusedWindow
|
||||
case "clock": return Prefs.showClock
|
||||
case "music": return Prefs.showMusic
|
||||
case "weather": return Prefs.showWeather
|
||||
case "systemTray": return Prefs.showSystemTray
|
||||
case "clipboard": return Prefs.showClipboard
|
||||
case "systemResources": return Prefs.showSystemResources
|
||||
case "notificationButton": return Prefs.showNotificationButton
|
||||
case "battery": return Prefs.showBattery
|
||||
case "controlCenterButton": return Prefs.showControlCenterButton
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
function getWidgetVisible(widgetId) {
|
||||
// Some widgets have additional visibility conditions
|
||||
switch (widgetId) {
|
||||
case "launcherButton": return true
|
||||
case "workspaceSwitcher": return true // Simplified - was NiriService.niriAvailable
|
||||
case "focusedWindow": return true
|
||||
case "clock": return true
|
||||
case "music": return true // Simplified - was MprisController.activePlayer
|
||||
case "weather": return true // Simplified - was complex weather condition
|
||||
case "systemTray": return true
|
||||
case "clipboard": return true
|
||||
case "systemResources": return true
|
||||
case "notificationButton": return true
|
||||
case "battery": return true
|
||||
case "controlCenterButton": return true
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
function getWidgetComponent(widgetId) {
|
||||
switch (widgetId) {
|
||||
case "launcherButton":
|
||||
return launcherButtonComponent
|
||||
case "workspaceSwitcher":
|
||||
return workspaceSwitcherComponent
|
||||
case "focusedWindow":
|
||||
return focusedWindowComponent
|
||||
case "clock":
|
||||
return clockComponent
|
||||
case "music":
|
||||
return mediaComponent
|
||||
case "weather":
|
||||
return weatherComponent
|
||||
case "systemTray":
|
||||
return systemTrayComponent
|
||||
case "clipboard":
|
||||
return clipboardComponent
|
||||
case "systemResources":
|
||||
return systemResourcesComponent
|
||||
case "notificationButton":
|
||||
return notificationButtonComponent
|
||||
case "battery":
|
||||
return batteryComponent
|
||||
case "controlCenterButton":
|
||||
return controlCenterButtonComponent
|
||||
case "spacer":
|
||||
return spacerComponent
|
||||
case "separator":
|
||||
return separatorComponent
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
@@ -142,6 +233,7 @@ PanelWindow {
|
||||
anchors.bottomMargin: Theme.spacingXS
|
||||
clip: true
|
||||
|
||||
// Dynamic left section
|
||||
Row {
|
||||
id: leftSection
|
||||
|
||||
@@ -150,67 +242,45 @@ PanelWindow {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
LauncherButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
isActive: appDrawerPopout ? appDrawerPopout.isVisible : false
|
||||
onClicked: {
|
||||
if (appDrawerPopout)
|
||||
appDrawerPopout.toggle();
|
||||
|
||||
Repeater {
|
||||
model: Prefs.topBarLeftWidgetsModel
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||
|
||||
property string widgetId: model.widgetId
|
||||
}
|
||||
}
|
||||
|
||||
WorkspaceSwitcher {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
screenName: root.screenName
|
||||
}
|
||||
|
||||
FocusedApp {
|
||||
id: focusedApp
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: Prefs.showFocusedWindow
|
||||
compactMode: topBarContent.spacingTight
|
||||
availableWidth: topBarContent.leftToMediaGap
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Clock {
|
||||
id: clock
|
||||
// Dynamic center section
|
||||
Row {
|
||||
id: centerSection
|
||||
|
||||
height: parent.height
|
||||
spacing: Theme.spacingS
|
||||
anchors.centerIn: parent
|
||||
compactMode: topBarContent.overlapping
|
||||
onClockClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
}
|
||||
}
|
||||
|
||||
Media {
|
||||
id: media
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: clock.left
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
visible: Prefs.showMusic && MprisController.activePlayer
|
||||
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
||||
onClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
}
|
||||
}
|
||||
|
||||
Weather {
|
||||
id: weather
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: clock.right
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
visible: Prefs.showWeather && WeatherService.weather.available && WeatherService.weather.temp > 0 && WeatherService.weather.tempF > 0
|
||||
onClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Center widgets model count:", Prefs.topBarCenterWidgetsModel.count)
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Prefs.topBarCenterWidgetsModel
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||
|
||||
property string widgetId: model.widgetId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic right section
|
||||
Row {
|
||||
id: rightSection
|
||||
|
||||
@@ -219,9 +289,82 @@ PanelWindow {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Right widgets model count:", Prefs.topBarRightWidgetsModel.count)
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Prefs.topBarRightWidgetsModel
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||
|
||||
property string widgetId: model.widgetId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Widget Components
|
||||
Component {
|
||||
id: launcherButtonComponent
|
||||
LauncherButton {
|
||||
isActive: appDrawerPopout ? appDrawerPopout.isVisible : false
|
||||
onClicked: {
|
||||
if (appDrawerPopout)
|
||||
appDrawerPopout.toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: workspaceSwitcherComponent
|
||||
WorkspaceSwitcher {
|
||||
screenName: root.screenName
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: focusedWindowComponent
|
||||
FocusedApp {
|
||||
compactMode: topBarContent.spacingTight
|
||||
availableWidth: topBarContent.leftToMediaGap
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: clockComponent
|
||||
Clock {
|
||||
compactMode: topBarContent.overlapping
|
||||
onClockClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaComponent
|
||||
Media {
|
||||
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
||||
onClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: weatherComponent
|
||||
Weather {
|
||||
onClicked: {
|
||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: systemTrayComponent
|
||||
SystemTrayBar {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: Prefs.showSystemTray
|
||||
onMenuRequested: (menu, item, x, y) => {
|
||||
systemTrayContextMenu.currentTrayMenu = menu;
|
||||
systemTrayContextMenu.currentTrayItem = item;
|
||||
@@ -231,7 +374,10 @@ PanelWindow {
|
||||
menu.menuVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: clipboardComponent
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 30
|
||||
@@ -240,8 +386,6 @@ PanelWindow {
|
||||
const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover;
|
||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: Prefs.showClipboard
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
@@ -252,7 +396,6 @@ PanelWindow {
|
||||
|
||||
MouseArea {
|
||||
id: clipboardArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
@@ -266,75 +409,84 @@ PanelWindow {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
active: Prefs.showSystemResources
|
||||
|
||||
sourceComponent: Component {
|
||||
CpuMonitor {
|
||||
toggleProcessList: () => {
|
||||
return processListPopout.toggle();
|
||||
}
|
||||
Component {
|
||||
id: systemResourcesComponent
|
||||
Row {
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
CpuMonitor {
|
||||
toggleProcessList: () => {
|
||||
return processListPopout.toggle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
active: Prefs.showSystemResources
|
||||
|
||||
sourceComponent: Component {
|
||||
RamMonitor {
|
||||
toggleProcessList: () => {
|
||||
return processListPopout.toggle();
|
||||
}
|
||||
RamMonitor {
|
||||
toggleProcessList: () => {
|
||||
return processListPopout.toggle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: notificationButtonComponent
|
||||
NotificationCenterButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
hasUnread: root.notificationCount > 0
|
||||
isActive: notificationCenter.notificationHistoryVisible
|
||||
onClicked: {
|
||||
notificationCenter.notificationHistoryVisible = !notificationCenter.notificationHistoryVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: batteryComponent
|
||||
Battery {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
batteryPopupVisible: batteryPopout.batteryPopupVisible
|
||||
onToggleBatteryPopup: {
|
||||
batteryPopout.batteryPopupVisible = !batteryPopout.batteryPopupVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: controlCenterButtonComponent
|
||||
ControlCenterButton {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
isActive: controlCenterPopout.controlCenterVisible
|
||||
onClicked: {
|
||||
controlCenterPopout.controlCenterVisible = !controlCenterPopout.controlCenterVisible;
|
||||
if (controlCenterPopout.controlCenterVisible) {
|
||||
if (NetworkService.wifiEnabled)
|
||||
NetworkService.scanWifi();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: spacerComponent
|
||||
Item {
|
||||
width: 20
|
||||
height: 30
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: separatorComponent
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: 20
|
||||
color: Theme.outline
|
||||
opacity: 0.3
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user