mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 23:42:51 -05:00
fix loader patterns in settings
- fix matugen command - fix focused window being wrong sometimes
This commit is contained in:
@@ -29,7 +29,6 @@ Singleton {
|
|||||||
property bool gtkThemingEnabled: false
|
property bool gtkThemingEnabled: false
|
||||||
property bool qtThemingEnabled: false
|
property bool qtThemingEnabled: false
|
||||||
property bool systemThemeGenerationInProgress: false
|
property bool systemThemeGenerationInProgress: false
|
||||||
property string matugenJson: ""
|
|
||||||
property var matugenColors: ({})
|
property var matugenColors: ({})
|
||||||
property bool extractionRequested: false
|
property bool extractionRequested: false
|
||||||
property int colorUpdateTrigger: 0
|
property int colorUpdateTrigger: 0
|
||||||
@@ -141,51 +140,33 @@ Singleton {
|
|||||||
Process {
|
Process {
|
||||||
id: matugenProcess
|
id: matugenProcess
|
||||||
|
|
||||||
command: ["matugen", "-v", "image", wallpaperPath, "--json", "hex"]
|
command: ["matugen", "image", wallpaperPath, "--json", "hex"]
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
id: matugenCollector
|
id: matugenCollector
|
||||||
|
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const out = matugenCollector.text
|
if (!matugenCollector.text) {
|
||||||
const startIndex = out.indexOf('{')
|
|
||||||
const endIndex = out.lastIndexOf('}')
|
|
||||||
let jsonStringOnly = ""
|
|
||||||
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
||||||
jsonStringOnly = out.substring(startIndex, endIndex + 1)
|
|
||||||
}
|
|
||||||
if (!jsonStringOnly.length) {
|
|
||||||
ToastService.wallpaperErrorStatus = "error"
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
ToastService.showError("Wallpaper Processing Failed: Empty JSON extracted from matugen output.")
|
ToastService.showError("Wallpaper Processing Failed: Empty JSON extracted from matugen output.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
root.matugenJson = jsonStringOnly
|
root.matugenColors = JSON.parse(matugenCollector.text)
|
||||||
root.matugenColors = JSON.parse(jsonStringOnly)
|
|
||||||
root.colorsUpdated()
|
root.colorsUpdated()
|
||||||
generateAppConfigs()
|
generateAppConfigs()
|
||||||
ToastService.clearWallpaperError()
|
ToastService.clearWallpaperError()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ToastService.wallpaperErrorStatus = "error"
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
const stderr = matugenErr.text
|
ToastService.showError("Wallpaper processing failed (JSON parse error after extraction)")
|
||||||
const msg = "Wallpaper processing failed (JSON parse error after extraction)"
|
|
||||||
+ (stderr ? `: ${stderr}` : ` with output: ${jsonStringOnly}`)
|
|
||||||
ToastService.showError(msg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stderr: StdioCollector {
|
|
||||||
id: matugenErr
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: code => {
|
onExited: code => {
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
ToastService.wallpaperErrorStatus = "error"
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
const stderr = matugenErr.text
|
ToastService.showError("Matugen command failed with exit code " + code)
|
||||||
const msg = "Matugen command failed with exit code " + code
|
|
||||||
+ (stderr ? `: ${stderr}` : ". No stderr output.")
|
|
||||||
ToastService.showError(msg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,16 +121,18 @@ DankModal {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: personalizationLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 0
|
active: settingsTabBar.currentIndex === 0
|
||||||
visible: active
|
visible: active
|
||||||
asynchronous: false
|
asynchronous: true
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
PersonalizationTab {}
|
PersonalizationTab {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: timeWeatherLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 1
|
active: settingsTabBar.currentIndex === 1
|
||||||
visible: active
|
visible: active
|
||||||
@@ -141,6 +143,7 @@ DankModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: widgetsLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 2
|
active: settingsTabBar.currentIndex === 2
|
||||||
visible: active
|
visible: active
|
||||||
@@ -151,6 +154,7 @@ DankModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: launcherLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 3
|
active: settingsTabBar.currentIndex === 3
|
||||||
visible: active
|
visible: active
|
||||||
@@ -161,10 +165,11 @@ DankModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
id: appearanceLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: settingsTabBar.currentIndex === 4
|
active: settingsTabBar.currentIndex === 4
|
||||||
visible: active
|
visible: active
|
||||||
asynchronous: false
|
asynchronous: true
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
AppearanceTab {}
|
AppearanceTab {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,5 +175,53 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: 36
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "notifications_active"
|
||||||
|
size: Theme.iconSizeSmall
|
||||||
|
color: SettingsData.notificationOverlayEnabled ? Theme.primary : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Notification Overlay"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Display all priorities over fullscreen apps"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall - 1
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: SettingsData.notificationOverlayEnabled
|
||||||
|
onToggled: (toggled) => SettingsData.setNotificationOverlayEnabled(toggled)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -20,482 +20,453 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
|
|
||||||
Loader {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
sourceComponent: appLauncherComponent
|
height: appLauncherSection.implicitHeight + Theme.spacingL * 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
|
||||||
|
|
||||||
Loader {
|
Column {
|
||||||
width: parent.width
|
id: appLauncherSection
|
||||||
sourceComponent: dockComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
anchors.fill: parent
|
||||||
width: parent.width
|
anchors.margins: Theme.spacingL
|
||||||
sourceComponent: recentlyUsedComponent
|
spacing: Theme.spacingM
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// App Launcher Component
|
DankToggle {
|
||||||
Component {
|
width: parent.width
|
||||||
id: appLauncherComponent
|
text: "Use OS Logo"
|
||||||
|
description: "Display operating system logo instead of apps icon"
|
||||||
|
checked: SettingsData.useOSLogo
|
||||||
|
onToggled: checked => {
|
||||||
|
return SettingsData.setUseOSLogo(checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StyledRect {
|
Row {
|
||||||
width: parent.width
|
width: parent.width - Theme.spacingL
|
||||||
height: appLauncherSection.implicitHeight + Theme.spacingL * 2
|
spacing: Theme.spacingL
|
||||||
radius: Theme.cornerRadius
|
visible: SettingsData.useOSLogo
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g,
|
opacity: visible ? 1 : 0
|
||||||
Theme.surfaceVariant.b, 0.3)
|
anchors.left: parent.left
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
anchors.leftMargin: Theme.spacingL
|
||||||
Theme.outline.b, 0.2)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: appLauncherSection
|
width: 120
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
anchors.fill: parent
|
StyledText {
|
||||||
anchors.margins: Theme.spacingL
|
text: "Color Override"
|
||||||
spacing: Theme.spacingM
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankTextField {
|
||||||
width: parent.width
|
width: 100
|
||||||
text: "Use OS Logo"
|
height: 28
|
||||||
description: "Display operating system logo instead of apps icon"
|
placeholderText: "#ffffff"
|
||||||
checked: SettingsData.useOSLogo
|
text: SettingsData.osLogoColorOverride
|
||||||
onToggled: checked => {
|
maximumLength: 7
|
||||||
return SettingsData.setUseOSLogo(checked)
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
}
|
topPadding: Theme.spacingXS
|
||||||
}
|
bottomPadding: Theme.spacingXS
|
||||||
|
onEditingFinished: {
|
||||||
Row {
|
var color = text.trim()
|
||||||
width: parent.width - Theme.spacingL
|
if (color === "" || /^#[0-9A-Fa-f]{6}$/.test(color))
|
||||||
spacing: Theme.spacingL
|
SettingsData.setOSLogoColorOverride(color)
|
||||||
visible: SettingsData.useOSLogo
|
else
|
||||||
opacity: visible ? 1 : 0
|
text = SettingsData.osLogoColorOverride
|
||||||
anchors.left: parent.left
|
}
|
||||||
anchors.leftMargin: Theme.spacingL
|
}
|
||||||
|
|
||||||
Column {
|
|
||||||
width: 120
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Color Override"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankTextField {
|
Column {
|
||||||
width: 100
|
width: 120
|
||||||
height: 28
|
spacing: Theme.spacingS
|
||||||
placeholderText: "#ffffff"
|
|
||||||
text: SettingsData.osLogoColorOverride
|
StyledText {
|
||||||
maximumLength: 7
|
text: "Brightness"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
topPadding: Theme.spacingXS
|
color: Theme.surfaceText
|
||||||
bottomPadding: Theme.spacingXS
|
font.weight: Font.Medium
|
||||||
onEditingFinished: {
|
}
|
||||||
var color = text.trim()
|
|
||||||
if (color === "" || /^#[0-9A-Fa-f]{6}$/.test(color))
|
DankSlider {
|
||||||
SettingsData.setOSLogoColorOverride(color)
|
width: 100
|
||||||
else
|
height: 20
|
||||||
text = SettingsData.osLogoColorOverride
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
value: Math.round(SettingsData.osLogoBrightness * 100)
|
||||||
|
unit: "%"
|
||||||
|
showValue: true
|
||||||
|
onSliderValueChanged: newValue => {
|
||||||
|
SettingsData.setOSLogoBrightness(
|
||||||
|
newValue / 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: 120
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Contrast"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
DankSlider {
|
||||||
|
width: 100
|
||||||
|
height: 20
|
||||||
|
minimum: 0
|
||||||
|
maximum: 200
|
||||||
|
value: Math.round(SettingsData.osLogoContrast * 100)
|
||||||
|
unit: "%"
|
||||||
|
showValue: true
|
||||||
|
onSliderValueChanged: newValue => {
|
||||||
|
SettingsData.setOSLogoContrast(
|
||||||
|
newValue / 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: dockSection.implicitHeight + Theme.spacingL * 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
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: dockSection
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "dock_to_bottom"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Dock"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Show Dock"
|
||||||
|
description: "Display a dock at the bottom of the screen with pinned and running applications"
|
||||||
|
checked: SettingsData.showDock
|
||||||
|
onToggled: checked => {
|
||||||
|
SettingsData.setShowDock(checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Auto-hide Dock"
|
||||||
|
description: "Hide the dock when not in use and reveal it when hovering near the bottom of the screen"
|
||||||
|
checked: SettingsData.dockAutoHide
|
||||||
|
visible: SettingsData.showDock
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
onToggled: checked => {
|
||||||
|
SettingsData.setDockAutoHide(checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: 120
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
visible: SettingsData.showDock
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Brightness"
|
text: "Dock Transparency"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
|
|
||||||
DankSlider {
|
DankSlider {
|
||||||
width: 100
|
width: parent.width
|
||||||
height: 20
|
height: 24
|
||||||
|
value: Math.round(SettingsData.dockTransparency * 100)
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
value: Math.round(SettingsData.osLogoBrightness * 100)
|
unit: ""
|
||||||
unit: "%"
|
|
||||||
showValue: true
|
showValue: true
|
||||||
onSliderValueChanged: newValue => {
|
onSliderValueChanged: newValue => {
|
||||||
SettingsData.setOSLogoBrightness(
|
SettingsData.setDockTransparency(
|
||||||
newValue / 100)
|
newValue / 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: recentlyUsedSection.implicitHeight + Theme.spacingL * 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
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: recentlyUsedSection
|
||||||
|
|
||||||
|
property var rankedAppsModel: {
|
||||||
|
var apps = []
|
||||||
|
for (var appId in (AppUsageHistoryData.appUsageRanking || {})) {
|
||||||
|
var appData = (AppUsageHistoryData.appUsageRanking || {})[appId]
|
||||||
|
apps.push({
|
||||||
|
"id": appId,
|
||||||
|
"name": appData.name,
|
||||||
|
"exec": appData.exec,
|
||||||
|
"icon": appData.icon,
|
||||||
|
"comment": appData.comment,
|
||||||
|
"usageCount": appData.usageCount,
|
||||||
|
"lastUsed": appData.lastUsed
|
||||||
|
})
|
||||||
|
}
|
||||||
|
apps.sort(function (a, b) {
|
||||||
|
if (a.usageCount !== b.usageCount)
|
||||||
|
return b.usageCount - a.usageCount
|
||||||
|
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
|
return apps.slice(0, 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "history"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Recently Used Apps"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - parent.children[0].width - parent.children[1].width
|
||||||
|
- clearAllButton.width - Theme.spacingM * 3
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
id: clearAllButton
|
||||||
|
|
||||||
|
iconName: "delete_sweep"
|
||||||
|
iconSize: Theme.iconSize - 2
|
||||||
|
iconColor: Theme.error
|
||||||
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g,
|
||||||
|
Theme.error.b, 0.12)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: {
|
||||||
|
AppUsageHistoryData.appUsageRanking = {}
|
||||||
|
SettingsData.saveSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
width: parent.width
|
||||||
|
text: "Apps are ordered by usage frequency, then last used, then alphabetically."
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: 120
|
id: rankedAppsList
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledText {
|
Repeater {
|
||||||
text: "Contrast"
|
model: recentlyUsedSection.rankedAppsModel
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
DankSlider {
|
delegate: Rectangle {
|
||||||
width: 100
|
width: rankedAppsList.width
|
||||||
height: 20
|
height: 48
|
||||||
minimum: 0
|
radius: Theme.cornerRadius
|
||||||
maximum: 200
|
color: Qt.rgba(Theme.surfaceContainer.r,
|
||||||
value: Math.round(SettingsData.osLogoContrast * 100)
|
Theme.surfaceContainer.g,
|
||||||
unit: "%"
|
Theme.surfaceContainer.b, 0.3)
|
||||||
showValue: true
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
onSliderValueChanged: newValue => {
|
Theme.outline.b, 0.1)
|
||||||
SettingsData.setOSLogoContrast(
|
border.width: 1
|
||||||
newValue / 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
Row {
|
||||||
NumberAnimation {
|
anchors.left: parent.left
|
||||||
duration: Theme.mediumDuration
|
anchors.leftMargin: Theme.spacingM
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dock Component
|
|
||||||
Component {
|
|
||||||
id: dockComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: dockSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: dockSection
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "dock_to_bottom"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Dock"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Show Dock"
|
|
||||||
description: "Display a dock at the bottom of the screen with pinned and running applications"
|
|
||||||
checked: SettingsData.showDock
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.setShowDock(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Auto-hide Dock"
|
|
||||||
description: "Hide the dock when not in use and reveal it when hovering near the bottom of the screen"
|
|
||||||
checked: SettingsData.dockAutoHide
|
|
||||||
visible: SettingsData.showDock
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.setDockAutoHide(checked)
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
visible: SettingsData.showDock
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Dock Transparency"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
DankSlider {
|
|
||||||
width: parent.width
|
|
||||||
height: 24
|
|
||||||
value: Math.round(SettingsData.dockTransparency * 100)
|
|
||||||
minimum: 0
|
|
||||||
maximum: 100
|
|
||||||
unit: ""
|
|
||||||
showValue: true
|
|
||||||
onSliderValueChanged: newValue => {
|
|
||||||
SettingsData.setDockTransparency(
|
|
||||||
newValue / 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recently Used Apps Component
|
|
||||||
Component {
|
|
||||||
id: recentlyUsedComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: recentlyUsedSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: recentlyUsedSection
|
|
||||||
|
|
||||||
property var rankedAppsModel: {
|
|
||||||
var apps = []
|
|
||||||
for (var appId in (AppUsageHistoryData.appUsageRanking || {})) {
|
|
||||||
var appData = (AppUsageHistoryData.appUsageRanking || {})[appId]
|
|
||||||
apps.push({
|
|
||||||
"id": appId,
|
|
||||||
"name": appData.name,
|
|
||||||
"exec": appData.exec,
|
|
||||||
"icon": appData.icon,
|
|
||||||
"comment": appData.comment,
|
|
||||||
"usageCount": appData.usageCount,
|
|
||||||
"lastUsed": appData.lastUsed
|
|
||||||
})
|
|
||||||
}
|
|
||||||
apps.sort(function (a, b) {
|
|
||||||
if (a.usageCount !== b.usageCount)
|
|
||||||
return b.usageCount - a.usageCount
|
|
||||||
|
|
||||||
return a.name.localeCompare(b.name)
|
|
||||||
})
|
|
||||||
return apps.slice(0, 20)
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "history"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Recently Used Apps"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: parent.width - parent.children[0].width - parent.children[1].width
|
|
||||||
- clearAllButton.width - Theme.spacingM * 3
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: clearAllButton
|
|
||||||
|
|
||||||
iconName: "delete_sweep"
|
|
||||||
iconSize: Theme.iconSize - 2
|
|
||||||
iconColor: Theme.error
|
|
||||||
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g,
|
|
||||||
Theme.error.b, 0.12)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: {
|
|
||||||
AppUsageHistoryData.appUsageRanking = {}
|
|
||||||
SettingsData.saveSettings()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
width: parent.width
|
|
||||||
text: "Apps are ordered by usage frequency, then last used, then alphabetically."
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: rankedAppsList
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: recentlyUsedSection.rankedAppsModel
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
|
||||||
width: rankedAppsList.width
|
|
||||||
height: 48
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r,
|
|
||||||
Theme.surfaceContainer.g,
|
|
||||||
Theme.surfaceContainer.b, 0.3)
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
||||||
Theme.outline.b, 0.1)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingM
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: (index + 1).toString()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.primary
|
|
||||||
width: 20
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Image {
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
source: modelData.icon ? "image://icon/" + modelData.icon : "image://icon/application-x-executable"
|
|
||||||
sourceSize.width: 24
|
|
||||||
sourceSize.height: 24
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onStatusChanged: {
|
|
||||||
if (status === Image.Error)
|
|
||||||
source = "image://icon/application-x-executable"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: modelData.name || "Unknown App"
|
text: (index + 1).toString()
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (!modelData.lastUsed)
|
|
||||||
return "Never used"
|
|
||||||
|
|
||||||
var date = new Date(modelData.lastUsed)
|
|
||||||
var now = new Date()
|
|
||||||
var diffMs = now - date
|
|
||||||
var diffMins = Math.floor(diffMs / (1000 * 60))
|
|
||||||
var diffHours = Math.floor(diffMs / (1000 * 60 * 60))
|
|
||||||
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))
|
|
||||||
if (diffMins < 1)
|
|
||||||
return "Last launched just now"
|
|
||||||
|
|
||||||
if (diffMins < 60)
|
|
||||||
return "Last launched " + diffMins + " minute"
|
|
||||||
+ (diffMins === 1 ? "" : "s") + " ago"
|
|
||||||
|
|
||||||
if (diffHours < 24)
|
|
||||||
return "Last launched " + diffHours + " hour"
|
|
||||||
+ (diffHours === 1 ? "" : "s") + " ago"
|
|
||||||
|
|
||||||
if (diffDays < 7)
|
|
||||||
return "Last launched " + diffDays + " day"
|
|
||||||
+ (diffDays === 1 ? "" : "s") + " ago"
|
|
||||||
|
|
||||||
return "Last launched " + date.toLocaleDateString()
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceVariantText
|
font.weight: Font.Medium
|
||||||
|
color: Theme.primary
|
||||||
|
width: 20
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
source: modelData.icon ? "image://icon/" + modelData.icon : "image://icon/application-x-executable"
|
||||||
|
sourceSize.width: 24
|
||||||
|
sourceSize.height: 24
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error)
|
||||||
|
source = "image://icon/application-x-executable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.name || "Unknown App"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
if (!modelData.lastUsed)
|
||||||
|
return "Never used"
|
||||||
|
|
||||||
|
var date = new Date(modelData.lastUsed)
|
||||||
|
var now = new Date()
|
||||||
|
var diffMs = now - date
|
||||||
|
var diffMins = Math.floor(diffMs / (1000 * 60))
|
||||||
|
var diffHours = Math.floor(diffMs / (1000 * 60 * 60))
|
||||||
|
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24))
|
||||||
|
if (diffMins < 1)
|
||||||
|
return "Last launched just now"
|
||||||
|
|
||||||
|
if (diffMins < 60)
|
||||||
|
return "Last launched " + diffMins + " minute"
|
||||||
|
+ (diffMins === 1 ? "" : "s") + " ago"
|
||||||
|
|
||||||
|
if (diffHours < 24)
|
||||||
|
return "Last launched " + diffHours + " hour"
|
||||||
|
+ (diffHours === 1 ? "" : "s") + " ago"
|
||||||
|
|
||||||
|
if (diffDays < 7)
|
||||||
|
return "Last launched " + diffDays + " day"
|
||||||
|
+ (diffDays === 1 ? "" : "s") + " ago"
|
||||||
|
|
||||||
|
return "Last launched " + date.toLocaleDateString()
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
circular: true
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: 16
|
||||||
|
iconColor: Theme.error
|
||||||
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g,
|
||||||
|
Theme.error.b, 0.12)
|
||||||
|
onClicked: {
|
||||||
|
var currentRanking = Object.assign(
|
||||||
|
{}, AppUsageHistoryData.appUsageRanking || {})
|
||||||
|
delete currentRanking[modelData.id]
|
||||||
|
AppUsageHistoryData.appUsageRanking = currentRanking
|
||||||
|
SettingsData.saveSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Theme.spacingM
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
circular: true
|
|
||||||
iconName: "close"
|
|
||||||
iconSize: 16
|
|
||||||
iconColor: Theme.error
|
|
||||||
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g,
|
|
||||||
Theme.error.b, 0.12)
|
|
||||||
onClicked: {
|
|
||||||
var currentRanking = Object.assign(
|
|
||||||
{}, AppUsageHistoryData.appUsageRanking || {})
|
|
||||||
delete currentRanking[modelData.id]
|
|
||||||
AppUsageHistoryData.appUsageRanking = currentRanking
|
|
||||||
SettingsData.saveSettings()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: recentlyUsedSection.rankedAppsModel.length
|
text: recentlyUsedSection.rankedAppsModel.length
|
||||||
=== 0 ? "No apps have been launched yet." : ""
|
=== 0 ? "No apps have been launched yet." : ""
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
visible: recentlyUsedSection.rankedAppsModel.length === 0
|
visible: recentlyUsedSection.rankedAppsModel.length === 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,438 +20,403 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
|
|
||||||
Loader {
|
// Time Format
|
||||||
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
sourceComponent: timeComponent
|
height: timeSection.implicitHeight + Theme.spacingL * 2
|
||||||
}
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
Loader {
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
width: parent.width
|
border.width: 1
|
||||||
sourceComponent: weatherComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time Format Component
|
|
||||||
Component {
|
|
||||||
id: timeComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: timeSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: timeSection
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "schedule"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Time Format"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "24-Hour Format"
|
|
||||||
description: "Use 24-hour time format instead of 12-hour AM/PM"
|
|
||||||
checked: SettingsData.use24HourClock
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return SettingsData.setClockFormat(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
id: timeSection
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
StyledText {
|
anchors.fill: parent
|
||||||
text: "Date Format"
|
anchors.margins: Theme.spacingL
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
DankDropdown {
|
|
||||||
width: parent.width
|
|
||||||
height: 50
|
|
||||||
text: "Top Bar Format"
|
|
||||||
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.clockDateFormat)
|
|
||||||
currentValue: {
|
|
||||||
// Find matching preset or show "Custom"
|
|
||||||
const presets = [{
|
|
||||||
"format": "ddd d",
|
|
||||||
"label": "Day Date"
|
|
||||||
}, {
|
|
||||||
"format": "ddd MMM d",
|
|
||||||
"label": "Day Month Date"
|
|
||||||
}, {
|
|
||||||
"format": "MMM d",
|
|
||||||
"label": "Month Date"
|
|
||||||
}, {
|
|
||||||
"format": "M/d",
|
|
||||||
"label": "Numeric (M/D)"
|
|
||||||
}, {
|
|
||||||
"format": "d/M",
|
|
||||||
"label": "Numeric (D/M)"
|
|
||||||
}, {
|
|
||||||
"format": "ddd d MMM yyyy",
|
|
||||||
"label": "Full with Year"
|
|
||||||
}, {
|
|
||||||
"format": "yyyy-MM-dd",
|
|
||||||
"label": "ISO Date"
|
|
||||||
}, {
|
|
||||||
"format": "dddd, MMMM d",
|
|
||||||
"label": "Full Day & Month"
|
|
||||||
}];
|
|
||||||
const match = presets.find((p) => {
|
|
||||||
return p.format === SettingsData.clockDateFormat;
|
|
||||||
});
|
|
||||||
return match ? match.label : "Custom: " + SettingsData.clockDateFormat;
|
|
||||||
}
|
|
||||||
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
|
|
||||||
onValueChanged: (value) => {
|
|
||||||
const formatMap = {
|
|
||||||
"Day Date": "ddd d",
|
|
||||||
"Day Month Date": "ddd MMM d",
|
|
||||||
"Month Date": "MMM d",
|
|
||||||
"Numeric (M/D)": "M/d",
|
|
||||||
"Numeric (D/M)": "d/M",
|
|
||||||
"Full with Year": "ddd d MMM yyyy",
|
|
||||||
"ISO Date": "yyyy-MM-dd",
|
|
||||||
"Full Day & Month": "dddd, MMMM d"
|
|
||||||
};
|
|
||||||
if (value === "Custom...") {
|
|
||||||
customFormatInput.visible = true;
|
|
||||||
} else {
|
|
||||||
customFormatInput.visible = false;
|
|
||||||
SettingsData.setClockDateFormat(formatMap[value]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankDropdown {
|
|
||||||
width: parent.width
|
|
||||||
height: 50
|
|
||||||
text: "Lock Screen Format"
|
|
||||||
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.lockDateFormat)
|
|
||||||
currentValue: {
|
|
||||||
// Find matching preset or show "Custom"
|
|
||||||
const presets = [{
|
|
||||||
"format": "ddd d",
|
|
||||||
"label": "Day Date"
|
|
||||||
}, {
|
|
||||||
"format": "ddd MMM d",
|
|
||||||
"label": "Day Month Date"
|
|
||||||
}, {
|
|
||||||
"format": "MMM d",
|
|
||||||
"label": "Month Date"
|
|
||||||
}, {
|
|
||||||
"format": "M/d",
|
|
||||||
"label": "Numeric (M/D)"
|
|
||||||
}, {
|
|
||||||
"format": "d/M",
|
|
||||||
"label": "Numeric (D/M)"
|
|
||||||
}, {
|
|
||||||
"format": "ddd d MMM yyyy",
|
|
||||||
"label": "Full with Year"
|
|
||||||
}, {
|
|
||||||
"format": "yyyy-MM-dd",
|
|
||||||
"label": "ISO Date"
|
|
||||||
}, {
|
|
||||||
"format": "dddd, MMMM d",
|
|
||||||
"label": "Full Day & Month"
|
|
||||||
}];
|
|
||||||
const match = presets.find((p) => {
|
|
||||||
return p.format === SettingsData.lockDateFormat;
|
|
||||||
});
|
|
||||||
return match ? match.label : "Custom: " + SettingsData.lockDateFormat;
|
|
||||||
}
|
|
||||||
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
|
|
||||||
onValueChanged: (value) => {
|
|
||||||
const formatMap = {
|
|
||||||
"Day Date": "ddd d",
|
|
||||||
"Day Month Date": "ddd MMM d",
|
|
||||||
"Month Date": "MMM d",
|
|
||||||
"Numeric (M/D)": "M/d",
|
|
||||||
"Numeric (D/M)": "d/M",
|
|
||||||
"Full with Year": "ddd d MMM yyyy",
|
|
||||||
"ISO Date": "yyyy-MM-dd",
|
|
||||||
"Full Day & Month": "dddd, MMMM d"
|
|
||||||
};
|
|
||||||
if (value === "Custom...") {
|
|
||||||
customLockFormatInput.visible = true;
|
|
||||||
} else {
|
|
||||||
customLockFormatInput.visible = false;
|
|
||||||
SettingsData.setLockDateFormat(formatMap[value]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankTextField {
|
|
||||||
id: customFormatInput
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
visible: false
|
|
||||||
placeholderText: "Enter custom top bar format (e.g., ddd MMM d)"
|
|
||||||
text: SettingsData.clockDateFormat
|
|
||||||
onTextChanged: {
|
|
||||||
if (visible && text)
|
|
||||||
SettingsData.setClockDateFormat(text);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankTextField {
|
|
||||||
id: customLockFormatInput
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
visible: false
|
|
||||||
placeholderText: "Enter custom lock screen format (e.g., dddd, MMMM d)"
|
|
||||||
text: SettingsData.lockDateFormat
|
|
||||||
onTextChanged: {
|
|
||||||
if (visible && text)
|
|
||||||
SettingsData.setLockDateFormat(text);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: formatHelp.implicitHeight + Theme.spacingM * 2
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2)
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: formatHelp
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingM
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Format Legend"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: Theme.spacingL
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• d - Day (1-31)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• dd - Day (01-31)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• ddd - Day name (Mon)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• dddd - Day name (Monday)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• M - Month (1-12)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• MM - Month (01-12)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• MMM - Month (Jan)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• MMMM - Month (January)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• yy - Year (24)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "• yyyy - Year (2024)"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weather Component
|
|
||||||
Component {
|
|
||||||
id: weatherComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: weatherSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: weatherSection
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
Row {
|
||||||
name: "cloud"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Weather"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Enable Weather"
|
|
||||||
description: "Show weather information in top bar and centcom center"
|
|
||||||
checked: SettingsData.weatherEnabled
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return SettingsData.setWeatherEnabled(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Fahrenheit"
|
|
||||||
description: "Use Fahrenheit instead of Celsius for temperature"
|
|
||||||
checked: SettingsData.useFahrenheit
|
|
||||||
enabled: SettingsData.weatherEnabled
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return SettingsData.setTemperatureUnit(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Auto Location"
|
|
||||||
description: "Allow wttr.in to determine location based on IP address"
|
|
||||||
checked: SettingsData.useAutoLocation
|
|
||||||
enabled: SettingsData.weatherEnabled
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return SettingsData.setAutoLocation(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: !SettingsData.useAutoLocation && SettingsData.weatherEnabled
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Location"
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Medium
|
|
||||||
}
|
|
||||||
|
|
||||||
DankLocationSearch {
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
currentLocation: SettingsData.weatherLocation
|
spacing: Theme.spacingM
|
||||||
placeholderText: "New York, NY"
|
|
||||||
onLocationSelected: (displayName, coordinates) => {
|
DankIcon {
|
||||||
SettingsData.setWeatherLocation(displayName, coordinates);
|
name: "schedule"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Time Format"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "24-Hour Format"
|
||||||
|
description: "Use 24-hour time format instead of 12-hour AM/PM"
|
||||||
|
checked: SettingsData.use24HourClock
|
||||||
|
onToggled: (checked) => {
|
||||||
|
return SettingsData.setClockFormat(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Date Format"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
text: "Top Bar Format"
|
||||||
|
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.clockDateFormat)
|
||||||
|
currentValue: {
|
||||||
|
// Find matching preset or show "Custom"
|
||||||
|
const presets = [{
|
||||||
|
"format": "ddd d",
|
||||||
|
"label": "Day Date"
|
||||||
|
}, {
|
||||||
|
"format": "ddd MMM d",
|
||||||
|
"label": "Day Month Date"
|
||||||
|
}, {
|
||||||
|
"format": "MMM d",
|
||||||
|
"label": "Month Date"
|
||||||
|
}, {
|
||||||
|
"format": "M/d",
|
||||||
|
"label": "Numeric (M/D)"
|
||||||
|
}, {
|
||||||
|
"format": "d/M",
|
||||||
|
"label": "Numeric (D/M)"
|
||||||
|
}, {
|
||||||
|
"format": "ddd d MMM yyyy",
|
||||||
|
"label": "Full with Year"
|
||||||
|
}, {
|
||||||
|
"format": "yyyy-MM-dd",
|
||||||
|
"label": "ISO Date"
|
||||||
|
}, {
|
||||||
|
"format": "dddd, MMMM d",
|
||||||
|
"label": "Full Day & Month"
|
||||||
|
}];
|
||||||
|
const match = presets.find((p) => {
|
||||||
|
return p.format === SettingsData.clockDateFormat;
|
||||||
|
});
|
||||||
|
return match ? match.label : "Custom: " + SettingsData.clockDateFormat;
|
||||||
|
}
|
||||||
|
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
|
||||||
|
onValueChanged: (value) => {
|
||||||
|
const formatMap = {
|
||||||
|
"Day Date": "ddd d",
|
||||||
|
"Day Month Date": "ddd MMM d",
|
||||||
|
"Month Date": "MMM d",
|
||||||
|
"Numeric (M/D)": "M/d",
|
||||||
|
"Numeric (D/M)": "d/M",
|
||||||
|
"Full with Year": "ddd d MMM yyyy",
|
||||||
|
"ISO Date": "yyyy-MM-dd",
|
||||||
|
"Full Day & Month": "dddd, MMMM d"
|
||||||
|
};
|
||||||
|
if (value === "Custom...") {
|
||||||
|
customFormatInput.visible = true;
|
||||||
|
} else {
|
||||||
|
customFormatInput.visible = false;
|
||||||
|
SettingsData.setClockDateFormat(formatMap[value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
text: "Lock Screen Format"
|
||||||
|
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.lockDateFormat)
|
||||||
|
currentValue: {
|
||||||
|
// Find matching preset or show "Custom"
|
||||||
|
const presets = [{
|
||||||
|
"format": "ddd d",
|
||||||
|
"label": "Day Date"
|
||||||
|
}, {
|
||||||
|
"format": "ddd MMM d",
|
||||||
|
"label": "Day Month Date"
|
||||||
|
}, {
|
||||||
|
"format": "MMM d",
|
||||||
|
"label": "Month Date"
|
||||||
|
}, {
|
||||||
|
"format": "M/d",
|
||||||
|
"label": "Numeric (M/D)"
|
||||||
|
}, {
|
||||||
|
"format": "d/M",
|
||||||
|
"label": "Numeric (D/M)"
|
||||||
|
}, {
|
||||||
|
"format": "ddd d MMM yyyy",
|
||||||
|
"label": "Full with Year"
|
||||||
|
}, {
|
||||||
|
"format": "yyyy-MM-dd",
|
||||||
|
"label": "ISO Date"
|
||||||
|
}, {
|
||||||
|
"format": "dddd, MMMM d",
|
||||||
|
"label": "Full Day & Month"
|
||||||
|
}];
|
||||||
|
const match = presets.find((p) => {
|
||||||
|
return p.format === SettingsData.lockDateFormat;
|
||||||
|
});
|
||||||
|
return match ? match.label : "Custom: " + SettingsData.lockDateFormat;
|
||||||
|
}
|
||||||
|
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
|
||||||
|
onValueChanged: (value) => {
|
||||||
|
const formatMap = {
|
||||||
|
"Day Date": "ddd d",
|
||||||
|
"Day Month Date": "ddd MMM d",
|
||||||
|
"Month Date": "MMM d",
|
||||||
|
"Numeric (M/D)": "M/d",
|
||||||
|
"Numeric (D/M)": "d/M",
|
||||||
|
"Full with Year": "ddd d MMM yyyy",
|
||||||
|
"ISO Date": "yyyy-MM-dd",
|
||||||
|
"Full Day & Month": "dddd, MMMM d"
|
||||||
|
};
|
||||||
|
if (value === "Custom...") {
|
||||||
|
customLockFormatInput.visible = true;
|
||||||
|
} else {
|
||||||
|
customLockFormatInput.visible = false;
|
||||||
|
SettingsData.setLockDateFormat(formatMap[value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankTextField {
|
||||||
|
id: customFormatInput
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
visible: false
|
||||||
|
placeholderText: "Enter custom top bar format (e.g., ddd MMM d)"
|
||||||
|
text: SettingsData.clockDateFormat
|
||||||
|
onTextChanged: {
|
||||||
|
if (visible && text)
|
||||||
|
SettingsData.setClockDateFormat(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankTextField {
|
||||||
|
id: customLockFormatInput
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
visible: false
|
||||||
|
placeholderText: "Enter custom lock screen format (e.g., dddd, MMMM d)"
|
||||||
|
text: SettingsData.lockDateFormat
|
||||||
|
onTextChanged: {
|
||||||
|
if (visible && text)
|
||||||
|
SettingsData.setLockDateFormat(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: formatHelp.implicitHeight + Theme.spacingM * 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: formatHelp
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingM
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Format Legend"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.primary
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• d - Day (1-31)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• dd - Day (01-31)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• ddd - Day name (Mon)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• dddd - Day name (Monday)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• M - Month (1-12)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• MM - Month (01-12)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• MMM - Month (Jan)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• MMMM - Month (January)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• yy - Year (24)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "• yyyy - Year (2024)"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weather
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: weatherSection.implicitHeight + Theme.spacingL * 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
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: weatherSection
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "cloud"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Weather"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Enable Weather"
|
||||||
|
description: "Show weather information in top bar and centcom center"
|
||||||
|
checked: SettingsData.weatherEnabled
|
||||||
|
onToggled: (checked) => {
|
||||||
|
return SettingsData.setWeatherEnabled(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Fahrenheit"
|
||||||
|
description: "Use Fahrenheit instead of Celsius for temperature"
|
||||||
|
checked: SettingsData.useFahrenheit
|
||||||
|
enabled: SettingsData.weatherEnabled
|
||||||
|
onToggled: (checked) => {
|
||||||
|
return SettingsData.setTemperatureUnit(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Auto Location"
|
||||||
|
description: "Allow wttr.in to determine location based on IP address"
|
||||||
|
checked: SettingsData.useAutoLocation
|
||||||
|
enabled: SettingsData.weatherEnabled
|
||||||
|
onToggled: (checked) => {
|
||||||
|
return SettingsData.setAutoLocation(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
visible: !SettingsData.useAutoLocation && SettingsData.weatherEnabled
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Location"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
DankLocationSearch {
|
||||||
|
width: parent.width
|
||||||
|
currentLocation: SettingsData.weatherLocation
|
||||||
|
placeholderText: "New York, NY"
|
||||||
|
onLocationSelected: (displayName, coordinates) => {
|
||||||
|
SettingsData.setWeatherLocation(displayName, coordinates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,499 +437,449 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
|
|
||||||
Loader {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
sourceComponent: headerComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
width: parent.width
|
|
||||||
sourceComponent: messageComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
width: parent.width
|
|
||||||
sourceComponent: sectionsComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
width: parent.width
|
|
||||||
sourceComponent: workspaceComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
width: parent.width
|
|
||||||
sourceComponent: workspaceIconsComponent
|
|
||||||
visible: SettingsData.hasNamedWorkspaces()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Header Component
|
|
||||||
Component {
|
|
||||||
id: headerComponent
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "widgets"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "refresh"
|
|
||||||
size: 14
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Reset"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: resetArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
SettingsData.setTopBarLeftWidgets(defaultLeftWidgets)
|
|
||||||
SettingsData.setTopBarCenterWidgets(defaultCenterWidgets)
|
|
||||||
SettingsData.setTopBarRightWidgets(defaultRightWidgets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message Component
|
|
||||||
Component {
|
|
||||||
id: messageComponent
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: messageText
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely."
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.outline
|
|
||||||
width: parent.width - Theme.spacingM * 2
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sections Component
|
|
||||||
Component {
|
|
||||||
id: sectionsComponent
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingL
|
|
||||||
|
|
||||||
WidgetsTabSection {
|
|
||||||
width: parent.width
|
|
||||||
title: "Left Section"
|
|
||||||
titleIcon: "format_align_left"
|
|
||||||
sectionId: "left"
|
|
||||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
|
||||||
items: widgetsTab.getItemsForSection("left")
|
|
||||||
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
|
||||||
widgetsTab.handleItemEnabledChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
enabled)
|
|
||||||
}
|
|
||||||
onItemOrderChanged: newOrder => {
|
|
||||||
widgetsTab.handleItemOrderChanged("left",
|
|
||||||
newOrder)
|
|
||||||
}
|
|
||||||
onAddWidget: sectionId => {
|
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
|
||||||
widgetSelectionPopup.targetSection = sectionId
|
|
||||||
widgetSelectionPopup.safeOpen()
|
|
||||||
}
|
|
||||||
onRemoveWidget: (sectionId, widgetIndex) => {
|
|
||||||
widgetsTab.removeWidgetFromSection(sectionId,
|
|
||||||
widgetIndex)
|
|
||||||
}
|
|
||||||
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
|
||||||
widgetsTab.handleSpacerSizeChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
newSize)
|
|
||||||
}
|
|
||||||
onCompactModeChanged: (widgetId, value) => {
|
|
||||||
if (widgetId === "clock") {
|
|
||||||
SettingsData.setClockCompactMode(value)
|
|
||||||
} else if (widgetId === "music") {
|
|
||||||
SettingsData.setMediaSize(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
|
||||||
widgetsTab.handleGpuSelectionChanged(
|
|
||||||
sectionId, widgetIndex, selectedIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetsTabSection {
|
|
||||||
width: parent.width
|
|
||||||
title: "Center Section"
|
|
||||||
titleIcon: "format_align_center"
|
|
||||||
sectionId: "center"
|
|
||||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
|
||||||
items: widgetsTab.getItemsForSection("center")
|
|
||||||
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
|
||||||
widgetsTab.handleItemEnabledChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
enabled)
|
|
||||||
}
|
|
||||||
onItemOrderChanged: newOrder => {
|
|
||||||
widgetsTab.handleItemOrderChanged("center",
|
|
||||||
newOrder)
|
|
||||||
}
|
|
||||||
onAddWidget: sectionId => {
|
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
|
||||||
widgetSelectionPopup.targetSection = sectionId
|
|
||||||
widgetSelectionPopup.safeOpen()
|
|
||||||
}
|
|
||||||
onRemoveWidget: (sectionId, widgetIndex) => {
|
|
||||||
widgetsTab.removeWidgetFromSection(sectionId,
|
|
||||||
widgetIndex)
|
|
||||||
}
|
|
||||||
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
|
||||||
widgetsTab.handleSpacerSizeChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
newSize)
|
|
||||||
}
|
|
||||||
onCompactModeChanged: (widgetId, value) => {
|
|
||||||
if (widgetId === "clock") {
|
|
||||||
SettingsData.setClockCompactMode(value)
|
|
||||||
} else if (widgetId === "music") {
|
|
||||||
SettingsData.setMediaSize(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
|
||||||
widgetsTab.handleGpuSelectionChanged(
|
|
||||||
sectionId, widgetIndex, selectedIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetsTabSection {
|
|
||||||
width: parent.width
|
|
||||||
title: "Right Section"
|
|
||||||
titleIcon: "format_align_right"
|
|
||||||
sectionId: "right"
|
|
||||||
allWidgets: widgetsTab.baseWidgetDefinitions
|
|
||||||
items: widgetsTab.getItemsForSection("right")
|
|
||||||
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
|
||||||
widgetsTab.handleItemEnabledChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
enabled)
|
|
||||||
}
|
|
||||||
onItemOrderChanged: newOrder => {
|
|
||||||
widgetsTab.handleItemOrderChanged("right",
|
|
||||||
newOrder)
|
|
||||||
}
|
|
||||||
onAddWidget: sectionId => {
|
|
||||||
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
|
||||||
widgetSelectionPopup.targetSection = sectionId
|
|
||||||
widgetSelectionPopup.safeOpen()
|
|
||||||
}
|
|
||||||
onRemoveWidget: (sectionId, widgetIndex) => {
|
|
||||||
widgetsTab.removeWidgetFromSection(sectionId,
|
|
||||||
widgetIndex)
|
|
||||||
}
|
|
||||||
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
|
||||||
widgetsTab.handleSpacerSizeChanged(sectionId,
|
|
||||||
itemId,
|
|
||||||
newSize)
|
|
||||||
}
|
|
||||||
onCompactModeChanged: (widgetId, value) => {
|
|
||||||
if (widgetId === "clock") {
|
|
||||||
SettingsData.setClockCompactMode(value)
|
|
||||||
} else if (widgetId === "music") {
|
|
||||||
SettingsData.setMediaSize(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
|
||||||
widgetsTab.handleGpuSelectionChanged(
|
|
||||||
sectionId, widgetIndex, selectedIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workspace Settings Component
|
|
||||||
Component {
|
|
||||||
id: workspaceComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: workspaceSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: workspaceSection
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
DankIcon {
|
||||||
width: parent.width
|
name: "widgets"
|
||||||
spacing: Theme.spacingM
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
DankIcon {
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
name: "view_module"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Workspace Settings"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Workspace Index Numbers"
|
|
||||||
description: "Show workspace index numbers in the top bar workspace switcher"
|
|
||||||
checked: SettingsData.showWorkspaceIndex
|
|
||||||
onToggled: checked => {
|
|
||||||
return SettingsData.setShowWorkspaceIndex(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
width: parent.width
|
|
||||||
text: "Workspace Padding"
|
|
||||||
description: "Always show a minimum of 3 workspaces, even if fewer are available"
|
|
||||||
checked: SettingsData.showWorkspacePadding
|
|
||||||
onToggled: checked => {
|
|
||||||
return SettingsData.setShowWorkspacePadding(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workspace Icons Component
|
|
||||||
Component {
|
|
||||||
id: workspaceIconsComponent
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: workspaceIconsSection.implicitHeight + Theme.spacingL * 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
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: workspaceIconsSection
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
Row {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "label"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Named Workspace Icons"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
text: "Top Bar Widget Management"
|
||||||
text: "Configure icons for named workspaces. Icons take priority over numbers when both are enabled."
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.weight: Font.Medium
|
||||||
color: Theme.outline
|
color: Theme.surfaceText
|
||||||
wrapMode: Text.WordWrap
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Item {
|
||||||
model: SettingsData.getNamedWorkspaces()
|
width: parent.width - 400
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: 80
|
||||||
height: workspaceIconRow.implicitHeight + Theme.spacingM
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g,
|
color: resetArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariant
|
||||||
Theme.surfaceContainer.b, 0.5)
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
border.width: 1
|
||||||
Theme.outline.b, 0.3)
|
border.color: resetArea.containsMouse ? Theme.outline : Qt.rgba(
|
||||||
border.width: 1
|
Theme.outline.r,
|
||||||
|
Theme.outline.g,
|
||||||
|
Theme.outline.b, 0.5)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: workspaceIconRow
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
anchors.left: parent.left
|
DankIcon {
|
||||||
anchors.right: parent.right
|
name: "refresh"
|
||||||
|
size: 14
|
||||||
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: Theme.spacingM
|
}
|
||||||
anchors.rightMargin: Theme.spacingM
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "\"" + modelData + "\""
|
text: "Reset"
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: resetArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
SettingsData.setTopBarLeftWidgets(defaultLeftWidgets)
|
||||||
|
SettingsData.setTopBarCenterWidgets(defaultCenterWidgets)
|
||||||
|
SettingsData.setTopBarRightWidgets(defaultRightWidgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: messageText
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely."
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
width: parent.width - Theme.spacingM * 2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
WidgetsTabSection {
|
||||||
|
width: parent.width
|
||||||
|
title: "Left Section"
|
||||||
|
titleIcon: "format_align_left"
|
||||||
|
sectionId: "left"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("left")
|
||||||
|
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
enabled)
|
||||||
|
}
|
||||||
|
onItemOrderChanged: newOrder => {
|
||||||
|
widgetsTab.handleItemOrderChanged("left",
|
||||||
|
newOrder)
|
||||||
|
}
|
||||||
|
onAddWidget: sectionId => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
onRemoveWidget: (sectionId, widgetIndex) => {
|
||||||
|
widgetsTab.removeWidgetFromSection(sectionId,
|
||||||
|
widgetIndex)
|
||||||
|
}
|
||||||
|
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
||||||
|
widgetsTab.handleSpacerSizeChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
newSize)
|
||||||
|
}
|
||||||
|
onCompactModeChanged: (widgetId, value) => {
|
||||||
|
if (widgetId === "clock") {
|
||||||
|
SettingsData.setClockCompactMode(value)
|
||||||
|
} else if (widgetId === "music") {
|
||||||
|
SettingsData.setMediaSize(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
||||||
|
widgetsTab.handleGpuSelectionChanged(
|
||||||
|
sectionId, widgetIndex, selectedIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsTabSection {
|
||||||
|
width: parent.width
|
||||||
|
title: "Center Section"
|
||||||
|
titleIcon: "format_align_center"
|
||||||
|
sectionId: "center"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("center")
|
||||||
|
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
enabled)
|
||||||
|
}
|
||||||
|
onItemOrderChanged: newOrder => {
|
||||||
|
widgetsTab.handleItemOrderChanged("center",
|
||||||
|
newOrder)
|
||||||
|
}
|
||||||
|
onAddWidget: sectionId => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
onRemoveWidget: (sectionId, widgetIndex) => {
|
||||||
|
widgetsTab.removeWidgetFromSection(sectionId,
|
||||||
|
widgetIndex)
|
||||||
|
}
|
||||||
|
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
||||||
|
widgetsTab.handleSpacerSizeChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
newSize)
|
||||||
|
}
|
||||||
|
onCompactModeChanged: (widgetId, value) => {
|
||||||
|
if (widgetId === "clock") {
|
||||||
|
SettingsData.setClockCompactMode(value)
|
||||||
|
} else if (widgetId === "music") {
|
||||||
|
SettingsData.setMediaSize(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
||||||
|
widgetsTab.handleGpuSelectionChanged(
|
||||||
|
sectionId, widgetIndex, selectedIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsTabSection {
|
||||||
|
width: parent.width
|
||||||
|
title: "Right Section"
|
||||||
|
titleIcon: "format_align_right"
|
||||||
|
sectionId: "right"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("right")
|
||||||
|
onItemEnabledChanged: (sectionId, itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
enabled)
|
||||||
|
}
|
||||||
|
onItemOrderChanged: newOrder => {
|
||||||
|
widgetsTab.handleItemOrderChanged("right",
|
||||||
|
newOrder)
|
||||||
|
}
|
||||||
|
onAddWidget: sectionId => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
onRemoveWidget: (sectionId, widgetIndex) => {
|
||||||
|
widgetsTab.removeWidgetFromSection(sectionId,
|
||||||
|
widgetIndex)
|
||||||
|
}
|
||||||
|
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
|
||||||
|
widgetsTab.handleSpacerSizeChanged(sectionId,
|
||||||
|
itemId,
|
||||||
|
newSize)
|
||||||
|
}
|
||||||
|
onCompactModeChanged: (widgetId, value) => {
|
||||||
|
if (widgetId === "clock") {
|
||||||
|
SettingsData.setClockCompactMode(value)
|
||||||
|
} else if (widgetId === "music") {
|
||||||
|
SettingsData.setMediaSize(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
|
||||||
|
widgetsTab.handleGpuSelectionChanged(
|
||||||
|
sectionId, widgetIndex, selectedIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: workspaceSection.implicitHeight + Theme.spacingL * 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
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: workspaceSection
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "view_module"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Workspace Settings"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Workspace Index Numbers"
|
||||||
|
description: "Show workspace index numbers in the top bar workspace switcher"
|
||||||
|
checked: SettingsData.showWorkspaceIndex
|
||||||
|
onToggled: checked => {
|
||||||
|
return SettingsData.setShowWorkspaceIndex(checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Workspace Padding"
|
||||||
|
description: "Always show a minimum of 3 workspaces, even if fewer are available"
|
||||||
|
checked: SettingsData.showWorkspacePadding
|
||||||
|
onToggled: checked => {
|
||||||
|
return SettingsData.setShowWorkspacePadding(checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: workspaceIconsSection.implicitHeight + Theme.spacingL * 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: SettingsData.hasNamedWorkspaces()
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: workspaceIconsSection
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "label"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Named Workspace Icons"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
width: parent.width
|
||||||
|
text: "Configure icons for named workspaces. Icons take priority over numbers when both are enabled."
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: SettingsData.getNamedWorkspaces()
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: workspaceIconRow.implicitHeight + Theme.spacingM
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g,
|
||||||
|
Theme.surfaceContainer.b, 0.5)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
|
Theme.outline.b, 0.3)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: workspaceIconRow
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 150
|
anchors.leftMargin: Theme.spacingM
|
||||||
elide: Text.ElideRight
|
anchors.rightMargin: Theme.spacingM
|
||||||
}
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIconPicker {
|
StyledText {
|
||||||
id: iconPicker
|
text: "\"" + modelData + "\""
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
Component.onCompleted: {
|
color: Theme.surfaceText
|
||||||
var iconData = SettingsData.getWorkspaceNameIcon(modelData)
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
if (iconData) {
|
width: 150
|
||||||
setIcon(iconData.value, iconData.type)
|
elide: Text.ElideRight
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onIconSelected: (iconName, iconType) => {
|
DankIconPicker {
|
||||||
SettingsData.setWorkspaceNameIcon(modelData, {
|
id: iconPicker
|
||||||
type: iconType,
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
value: iconName
|
|
||||||
})
|
|
||||||
setIcon(iconName, iconType)
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Component.onCompleted: {
|
||||||
target: SettingsData
|
|
||||||
function onWorkspaceIconsUpdated() {
|
|
||||||
var iconData = SettingsData.getWorkspaceNameIcon(modelData)
|
var iconData = SettingsData.getWorkspaceNameIcon(modelData)
|
||||||
if (iconData) {
|
if (iconData) {
|
||||||
iconPicker.setIcon(iconData.value, iconData.type)
|
setIcon(iconData.value, iconData.type)
|
||||||
} else {
|
}
|
||||||
iconPicker.setIcon("", "icon")
|
}
|
||||||
|
|
||||||
|
onIconSelected: (iconName, iconType) => {
|
||||||
|
SettingsData.setWorkspaceNameIcon(modelData, {
|
||||||
|
type: iconType,
|
||||||
|
value: iconName
|
||||||
|
})
|
||||||
|
setIcon(iconName, iconType)
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onWorkspaceIconsUpdated() {
|
||||||
|
var iconData = SettingsData.getWorkspaceNameIcon(modelData)
|
||||||
|
if (iconData) {
|
||||||
|
iconPicker.setIcon(iconData.value, iconData.type)
|
||||||
|
} else {
|
||||||
|
iconPicker.setIcon("", "icon")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: clearMouseArea.containsMouse ? Theme.errorHover : Theme.surfaceContainer
|
color: clearMouseArea.containsMouse ? Theme.errorHover : Theme.surfaceContainer
|
||||||
border.color: clearMouseArea.containsMouse ? Theme.error : Theme.outline
|
border.color: clearMouseArea.containsMouse ? Theme.error : Theme.outline
|
||||||
border.width: 1
|
border.width: 1
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "close"
|
name: "close"
|
||||||
size: 16
|
size: 16
|
||||||
color: clearMouseArea.containsMouse ? Theme.error : Theme.outline
|
color: clearMouseArea.containsMouse ? Theme.error : Theme.outline
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: clearMouseArea
|
id: clearMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
SettingsData.removeWorkspaceNameIcon(modelData)
|
SettingsData.removeWorkspaceNameIcon(modelData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width - 150 - 240 - 28 - Theme.spacingM * 4
|
width: parent.width - 150 - 240 - 28 - Theme.spacingM * 4
|
||||||
height: 1
|
height: 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -938,6 +888,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DankWidgetSelectionPopup {
|
DankWidgetSelectionPopup {
|
||||||
id: widgetSelectionPopup
|
id: widgetSelectionPopup
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ Singleton {
|
|||||||
handleWorkspacesChanged(event.WorkspacesChanged)
|
handleWorkspacesChanged(event.WorkspacesChanged)
|
||||||
} else if (event.WorkspaceActivated) {
|
} else if (event.WorkspaceActivated) {
|
||||||
handleWorkspaceActivated(event.WorkspaceActivated)
|
handleWorkspaceActivated(event.WorkspaceActivated)
|
||||||
|
} else if (event.WorkspaceActiveWindowChanged) {
|
||||||
|
handleWorkspaceActiveWindowChanged(event.WorkspaceActiveWindowChanged)
|
||||||
} else if (event.WindowsChanged) {
|
} else if (event.WindowsChanged) {
|
||||||
handleWindowsChanged(event.WindowsChanged)
|
handleWindowsChanged(event.WindowsChanged)
|
||||||
} else if (event.WindowClosed) {
|
} else if (event.WindowClosed) {
|
||||||
@@ -153,6 +155,49 @@ Singleton {
|
|||||||
workspacesChanged()
|
workspacesChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleWorkspaceActiveWindowChanged(data) {
|
||||||
|
// Update the focused window when workspace's active window changes
|
||||||
|
// This is crucial for handling floating window close scenarios
|
||||||
|
if (data.active_window_id !== null && data.active_window_id !== undefined) {
|
||||||
|
focusedWindowId = String(data.active_window_id)
|
||||||
|
focusedWindowIndex = windows.findIndex(w => w.id == data.active_window_id)
|
||||||
|
|
||||||
|
// Create new windows array with updated focus states to trigger property change
|
||||||
|
let updatedWindows = []
|
||||||
|
for (let i = 0; i < windows.length; i++) {
|
||||||
|
let w = windows[i]
|
||||||
|
let updatedWindow = {}
|
||||||
|
for (let prop in w) {
|
||||||
|
updatedWindow[prop] = w[prop]
|
||||||
|
}
|
||||||
|
updatedWindow.is_focused = (w.id == data.active_window_id)
|
||||||
|
updatedWindows.push(updatedWindow)
|
||||||
|
}
|
||||||
|
windows = updatedWindows
|
||||||
|
|
||||||
|
updateFocusedWindow()
|
||||||
|
} else {
|
||||||
|
// No active window in this workspace
|
||||||
|
focusedWindowId = ""
|
||||||
|
focusedWindowIndex = -1
|
||||||
|
|
||||||
|
// Create new windows array with cleared focus states for this workspace
|
||||||
|
let updatedWindows = []
|
||||||
|
for (let i = 0; i < windows.length; i++) {
|
||||||
|
let w = windows[i]
|
||||||
|
let updatedWindow = {}
|
||||||
|
for (let prop in w) {
|
||||||
|
updatedWindow[prop] = w[prop]
|
||||||
|
}
|
||||||
|
updatedWindow.is_focused = w.workspace_id == data.workspace_id ? false : w.is_focused
|
||||||
|
updatedWindows.push(updatedWindow)
|
||||||
|
}
|
||||||
|
windows = updatedWindows
|
||||||
|
|
||||||
|
updateFocusedWindow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleWindowsChanged(data) {
|
function handleWindowsChanged(data) {
|
||||||
windows = [...data.windows].sort((a, b) => a.id - b.id)
|
windows = [...data.windows].sort((a, b) => a.id - b.id)
|
||||||
updateFocusedWindow()
|
updateFocusedWindow()
|
||||||
|
|||||||
Reference in New Issue
Block a user