Settings: better horizontal dividers
This commit is contained in:
parent
7c2d2b4d66
commit
63eeb40c64
6 changed files with 980 additions and 856 deletions
|
|
@ -1,26 +1,24 @@
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Components
|
||||||
import qs.Settings
|
import qs.Settings
|
||||||
import qs.Widgets.SettingsWindow.Tabs
|
import qs.Widgets.SettingsWindow.Tabs
|
||||||
import qs.Widgets.SettingsWindow.Tabs.Components
|
import qs.Widgets.SettingsWindow.Tabs.Components
|
||||||
import qs.Components
|
|
||||||
|
|
||||||
PanelWithOverlay {
|
PanelWithOverlay {
|
||||||
id: panelMain
|
id: panelMain
|
||||||
|
|
||||||
property int activeTabIndex: 0
|
property int activeTabIndex: 0
|
||||||
|
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
|
||||||
|
|
||||||
// Function to show wallpaper selector
|
// Function to show wallpaper selector
|
||||||
function showWallpaperSelector() {
|
function showWallpaperSelector() {
|
||||||
if (wallpaperSelector) {
|
if (wallpaperSelector)
|
||||||
wallpaperSelector.show();
|
wallpaperSelector.show();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to show settings window
|
// Function to show settings window
|
||||||
|
|
@ -28,129 +26,138 @@ PanelWithOverlay {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Handle activeTabIndex changes
|
|
||||||
onActiveTabIndexChanged: {
|
|
||||||
if (activeTabIndex >= 0 && activeTabIndex <= 8) {
|
|
||||||
loadComponentForTab(activeTabIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to load component for a specific tab
|
// Function to load component for a specific tab
|
||||||
function loadComponentForTab(tabIndex) {
|
function loadComponentForTab(tabIndex) {
|
||||||
const componentMap = {
|
const componentMap = {
|
||||||
0: generalSettings,
|
"0": generalSettings,
|
||||||
1: barSettings,
|
"1": barSettings,
|
||||||
2: timeWeatherSettings,
|
"2": timeWeatherSettings,
|
||||||
3: recordingSettings,
|
"3": recordingSettings,
|
||||||
4: networkSettings,
|
"4": networkSettings,
|
||||||
5: displaySettings,
|
"5": displaySettings,
|
||||||
6: wallpaperSettings,
|
"6": wallpaperSettings,
|
||||||
7: miscSettings,
|
"7": miscSettings,
|
||||||
8: aboutSettings
|
"8": aboutSettings
|
||||||
};
|
};
|
||||||
|
const tabNames = ["General", "Bar", "Time & Weather", "Screen Recorder", "Network", "Display", "Wallpaper", "Misc", "About"];
|
||||||
const tabNames = [
|
|
||||||
"General",
|
|
||||||
"Bar",
|
|
||||||
"Time & Weather",
|
|
||||||
"Screen Recorder",
|
|
||||||
"Network",
|
|
||||||
"Display",
|
|
||||||
"Wallpaper",
|
|
||||||
"Misc",
|
|
||||||
"About"
|
|
||||||
];
|
|
||||||
|
|
||||||
if (componentMap[tabIndex]) {
|
if (componentMap[tabIndex]) {
|
||||||
settingsLoader.sourceComponent = componentMap[tabIndex];
|
settingsLoader.sourceComponent = componentMap[tabIndex];
|
||||||
if (tabName) {
|
if (tabName)
|
||||||
tabName.text = tabNames[tabIndex];
|
tabName.text = tabNames[tabIndex];
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||||
|
// Handle activeTabIndex changes
|
||||||
|
onActiveTabIndexChanged: {
|
||||||
|
if (activeTabIndex >= 0 && activeTabIndex <= 8)
|
||||||
|
loadComponentForTab(activeTabIndex);
|
||||||
|
|
||||||
|
}
|
||||||
// Add safety checks for component loading
|
// Add safety checks for component loading
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
// Ensure we start with a valid tab
|
// Ensure we start with a valid tab
|
||||||
if (activeTabIndex < 0 || activeTabIndex > 8) {
|
if (activeTabIndex < 0 || activeTabIndex > 8)
|
||||||
activeTabIndex = 0;
|
activeTabIndex = 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
// Cleanup when window is hidden
|
// Cleanup when window is hidden
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
// Reset to default tab when hiding to prevent state issues
|
// Reset to default tab when hiding to prevent state issues
|
||||||
activeTabIndex = 0;
|
activeTabIndex = 0;
|
||||||
if (tabName) {
|
if (tabName)
|
||||||
tabName.text = "General";
|
tabName.text = "General";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: generalSettings
|
id: generalSettings
|
||||||
General {}
|
|
||||||
|
General {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: barSettings
|
id: barSettings
|
||||||
Bar {}
|
|
||||||
|
Bar {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: timeWeatherSettings
|
id: timeWeatherSettings
|
||||||
TimeWeather {}
|
|
||||||
|
TimeWeather {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: recordingSettings
|
id: recordingSettings
|
||||||
Recording {}
|
|
||||||
|
Recording {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: networkSettings
|
id: networkSettings
|
||||||
Network {}
|
|
||||||
|
Network {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: miscSettings
|
id: miscSettings
|
||||||
Misc {}
|
|
||||||
|
Misc {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: aboutSettings
|
id: aboutSettings
|
||||||
About {}
|
|
||||||
|
About {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: displaySettings
|
id: displaySettings
|
||||||
Display {}
|
|
||||||
|
Display {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: wallpaperSettings
|
id: wallpaperSettings
|
||||||
Wallpaper {}
|
|
||||||
|
Wallpaper {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: settingsWindowRect
|
id: settingsWindowRect
|
||||||
|
|
||||||
implicitWidth: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 2 : 600
|
implicitWidth: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 2 : 600
|
||||||
implicitHeight: Quickshell.screens.length > 0 ? Quickshell.screens[0].height / 2 : 400
|
implicitHeight: Quickshell.screens.length > 0 ? Quickshell.screens[0].height / 2 : 400
|
||||||
visible: parent.visible
|
visible: parent.visible
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
// Center the settings window on screen
|
// Center the settings window on screen
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
|
|
||||||
color: Theme.backgroundPrimary
|
color: Theme.backgroundPrimary
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 20
|
radius: 20
|
||||||
|
|
@ -167,11 +174,16 @@ PanelWithOverlay {
|
||||||
shadowVerticalOffset: 2
|
shadowVerticalOffset: 2
|
||||||
shadowBlur: 12
|
shadowBlur: 12
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: settings
|
id: settings
|
||||||
|
|
||||||
color: Theme.backgroundPrimary
|
color: Theme.backgroundPrimary
|
||||||
|
topRightRadius: 20
|
||||||
|
bottomRightRadius: 20
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: tabs.right
|
left: tabs.right
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
|
@ -179,19 +191,19 @@ PanelWithOverlay {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
margins: 12
|
margins: 12
|
||||||
}
|
}
|
||||||
topRightRadius: 20
|
|
||||||
bottomRightRadius: 20
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: headerArea
|
id: headerArea
|
||||||
|
|
||||||
|
height: 48
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
margins: 16
|
margins: 16
|
||||||
}
|
}
|
||||||
height: 48
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -199,15 +211,8 @@ PanelWithOverlay {
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: tabName
|
id: tabName
|
||||||
text: wallpaperSelector.visible ? "Select Wallpaper" : (activeTabIndex === 0 ? "General" :
|
|
||||||
activeTabIndex === 1 ? "Bar" :
|
text: wallpaperSelector.visible ? "Select Wallpaper" : (activeTabIndex === 0 ? "General" : activeTabIndex === 1 ? "Bar" : activeTabIndex === 2 ? "Time & Weather" : activeTabIndex === 3 ? "Screen Recorder" : activeTabIndex === 4 ? "Network" : activeTabIndex === 5 ? "Display" : activeTabIndex === 6 ? "Wallpaper" : activeTabIndex === 7 ? "Misc" : activeTabIndex === 8 ? "About" : "General")
|
||||||
activeTabIndex === 2 ? "Time & Weather" :
|
|
||||||
activeTabIndex === 3 ? "Screen Recorder" :
|
|
||||||
activeTabIndex === 4 ? "Network" :
|
|
||||||
activeTabIndex === 5 ? "Display" :
|
|
||||||
activeTabIndex === 6 ? "Wallpaper" :
|
|
||||||
activeTabIndex === 7 ? "Misc" :
|
|
||||||
activeTabIndex === 8 ? "About" : "General")
|
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.bold: true
|
font.bold: true
|
||||||
color: Theme.textPrimary
|
color: Theme.textPrimary
|
||||||
|
|
@ -243,10 +248,12 @@ PanelWithOverlay {
|
||||||
color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: wallpaperButtonArea
|
id: wallpaperButtonArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
@ -255,6 +262,7 @@ PanelWithOverlay {
|
||||||
wallpaperSelector.show();
|
wallpaperSelector.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -275,29 +283,36 @@ PanelWithOverlay {
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: closeButtonArea
|
id: closeButtonArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: panelMain.dismiss()
|
onClicked: panelMain.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
height: 1
|
||||||
|
color: Theme.outline
|
||||||
|
opacity: 0.3
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: headerArea.bottom
|
top: headerArea.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
margins: 16
|
margins: 16
|
||||||
}
|
}
|
||||||
height: 1
|
|
||||||
color: Theme.outline
|
|
||||||
opacity: 0.3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: settingsContainer
|
id: settingsContainer
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: headerArea.bottom
|
top: headerArea.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
|
@ -310,6 +325,7 @@ PanelWithOverlay {
|
||||||
// Simplified single loader approach
|
// Simplified single loader approach
|
||||||
Loader {
|
Loader {
|
||||||
id: settingsLoader
|
id: settingsLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceComponent: generalSettings
|
sourceComponent: generalSettings
|
||||||
}
|
}
|
||||||
|
|
@ -317,13 +333,17 @@ PanelWithOverlay {
|
||||||
// Wallpaper Selector Component
|
// Wallpaper Selector Component
|
||||||
WallpaperSelector {
|
WallpaperSelector {
|
||||||
id: wallpaperSelector
|
id: wallpaperSelector
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: tabs
|
id: tabs
|
||||||
|
|
||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
width: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 9 : 100
|
width: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 9 : 100
|
||||||
height: settingsWindowRect.height
|
height: settingsWindowRect.height
|
||||||
|
|
@ -340,17 +360,35 @@ PanelWithOverlay {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
model: [
|
|
||||||
{ icon: "tune", text: "General" },
|
model: [{
|
||||||
{ icon: "space_dashboard", text: "Bar" },
|
"icon": "tune",
|
||||||
{ icon: "schedule", text: "Time & Weather" },
|
"text": "General"
|
||||||
{ icon: "photo_camera", text: "Screen Recorder" },
|
}, {
|
||||||
{ icon: "wifi", text: "Network" },
|
"icon": "space_dashboard",
|
||||||
{ icon: "monitor", text: "Display" },
|
"text": "Bar"
|
||||||
{ icon: "wallpaper", text: "Wallpaper" },
|
}, {
|
||||||
{ icon: "settings_suggest", text: "Misc" },
|
"icon": "schedule",
|
||||||
{ icon: "info", text: "About" }
|
"text": "Time & Weather"
|
||||||
]
|
}, {
|
||||||
|
"icon": "photo_camera",
|
||||||
|
"text": "Screen Recorder"
|
||||||
|
}, {
|
||||||
|
"icon": "wifi",
|
||||||
|
"text": "Network"
|
||||||
|
}, {
|
||||||
|
"icon": "monitor",
|
||||||
|
"text": "Display"
|
||||||
|
}, {
|
||||||
|
"icon": "wallpaper",
|
||||||
|
"text": "Wallpaper"
|
||||||
|
}, {
|
||||||
|
"icon": "settings_suggest",
|
||||||
|
"text": "Misc"
|
||||||
|
}, {
|
||||||
|
"icon": "info",
|
||||||
|
"text": "About"
|
||||||
|
}]
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: tabs.width
|
width: tabs.width
|
||||||
|
|
@ -363,6 +401,7 @@ PanelWithOverlay {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: activeIndicator
|
id: activeIndicator
|
||||||
|
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.preferredWidth: 3
|
Layout.preferredWidth: 3
|
||||||
Layout.preferredHeight: 24
|
Layout.preferredHeight: 24
|
||||||
|
|
@ -370,11 +409,19 @@ PanelWithOverlay {
|
||||||
radius: 2
|
radius: 2
|
||||||
color: Theme.accentPrimary
|
color: Theme.accentPrimary
|
||||||
opacity: index === activeTabIndex ? 1 : 0
|
opacity: index === activeTabIndex ? 1 : 0
|
||||||
Behavior on opacity { NumberAnimation { duration: 200 } }
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: icon
|
id: icon
|
||||||
|
|
||||||
text: modelData.icon
|
text: modelData.icon
|
||||||
font.family: "Material Symbols Outlined"
|
font.family: "Material Symbols Outlined"
|
||||||
font.pixelSize: 24
|
font.pixelSize: 24
|
||||||
|
|
@ -390,12 +437,11 @@ PanelWithOverlay {
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
text: modelData.text
|
text: modelData.text
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: index === activeTabIndex ? Theme.accentPrimary :
|
color: index === activeTabIndex ? Theme.accentPrimary : (tabMouseArea.containsMouse ? Theme.accentPrimary : Theme.textSecondary)
|
||||||
(tabMouseArea.containsMouse ? Theme.accentPrimary : Theme.textSecondary)
|
font.weight: index === activeTabIndex ? Font.DemiBold : (tabMouseArea.containsMouse ? Font.DemiBold : Font.Normal)
|
||||||
font.weight: index === activeTabIndex ? Font.DemiBold :
|
|
||||||
(tabMouseArea.containsMouse ? Font.DemiBold : Font.Normal)
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 24
|
Layout.preferredHeight: 24
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||||
|
|
@ -403,10 +449,12 @@ PanelWithOverlay {
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: tabMouseArea
|
id: tabMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
@ -424,9 +472,15 @@ PanelWithOverlay {
|
||||||
visible: index < (repeater.count - 1)
|
visible: index < (repeater.count - 1)
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import qs.Settings
|
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
import qs.Settings
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -15,131 +15,144 @@ Item {
|
||||||
property var contributors: []
|
property var contributors: []
|
||||||
property string githubDataPath: Settings.settingsDir + "github_data.json"
|
property string githubDataPath: Settings.settingsDir + "github_data.json"
|
||||||
|
|
||||||
|
function loadFromFile() {
|
||||||
|
const now = Date.now();
|
||||||
|
const data = githubData;
|
||||||
|
if (!data.timestamp || (now - data.timestamp > 3.6e+06)) {
|
||||||
|
console.log("[About] Cache expired or missing, fetching new data from GitHub...");
|
||||||
|
fetchFromGitHub();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
console.log("[About] Loading cached GitHub data (age: " + Math.round((now - data.timestamp) / 60000) + " minutes)");
|
||||||
|
if (data.version)
|
||||||
|
root.latestVersion = data.version;
|
||||||
|
|
||||||
|
if (data.contributors)
|
||||||
|
root.contributors = data.contributors;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchFromGitHub() {
|
||||||
|
versionProcess.running = true;
|
||||||
|
contributorsProcess.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveData() {
|
||||||
|
githubData.timestamp = Date.now();
|
||||||
|
Qt.callLater(() => {
|
||||||
|
githubDataFile.writeAdapter();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: currentVersionProcess
|
id: currentVersionProcess
|
||||||
|
|
||||||
command: ["sh", "-c", "cd " + Quickshell.shellDir + " && git describe --tags --abbrev=0 2>/dev/null || echo 'Unknown'"]
|
command: ["sh", "-c", "cd " + Quickshell.shellDir + " && git describe --tags --abbrev=0 2>/dev/null || echo 'Unknown'"]
|
||||||
|
Component.onCompleted: {
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const version = text.trim()
|
const version = text.trim();
|
||||||
if (version && version !== "Unknown") {
|
if (version && version !== "Unknown") {
|
||||||
root.currentVersion = version
|
root.currentVersion = version;
|
||||||
} else {
|
} else {
|
||||||
|
currentVersionProcess.command = ["sh", "-c", "cd " + Quickshell.shellDir + " && cat package.json 2>/dev/null | grep '\"version\"' | cut -d'\"' -f4 || echo 'Unknown'"];
|
||||||
|
currentVersionProcess.running = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
currentVersionProcess.command = ["sh", "-c", "cd " + Quickshell.shellDir + " && cat package.json 2>/dev/null | grep '\"version\"' | cut -d'\"' -f4 || echo 'Unknown'"]
|
|
||||||
currentVersionProcess.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
running = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
id: githubDataFile
|
id: githubDataFile
|
||||||
|
|
||||||
path: root.githubDataPath
|
path: root.githubDataPath
|
||||||
blockLoading: true
|
blockLoading: true
|
||||||
printErrors: true
|
printErrors: true
|
||||||
watchChanges: true
|
watchChanges: true
|
||||||
|
onFileChanged: githubDataFile.reload()
|
||||||
|
onLoaded: loadFromFile()
|
||||||
|
onLoadFailed: function(error) {
|
||||||
|
console.log("GitHub data file doesn't exist yet, creating it...");
|
||||||
|
githubData.version = "Unknown";
|
||||||
|
githubData.contributors = [];
|
||||||
|
githubData.timestamp = 0;
|
||||||
|
githubDataFile.writeAdapter();
|
||||||
|
fetchFromGitHub();
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (path)
|
||||||
|
reload();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: githubData
|
id: githubData
|
||||||
|
|
||||||
property string version: "Unknown"
|
property string version: "Unknown"
|
||||||
property var contributors: []
|
property var contributors: []
|
||||||
property double timestamp: 0
|
property double timestamp: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileChanged: githubDataFile.reload()
|
|
||||||
onLoaded: loadFromFile()
|
|
||||||
onLoadFailed: function(error) {
|
|
||||||
console.log("GitHub data file doesn't exist yet, creating it...")
|
|
||||||
githubData.version = "Unknown"
|
|
||||||
githubData.contributors = []
|
|
||||||
githubData.timestamp = 0
|
|
||||||
githubDataFile.writeAdapter()
|
|
||||||
fetchFromGitHub()
|
|
||||||
}
|
|
||||||
Component.onCompleted: if (path) reload()
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadFromFile() {
|
|
||||||
const now = Date.now()
|
|
||||||
const data = githubData
|
|
||||||
|
|
||||||
if (!data.timestamp || (now - data.timestamp > 3600000)) {
|
|
||||||
console.log("[About] Cache expired or missing, fetching new data from GitHub...")
|
|
||||||
fetchFromGitHub()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
console.log("[About] Loading cached GitHub data (age: " + Math.round((now - data.timestamp) / 60000) + " minutes)")
|
|
||||||
if (data.version) {
|
|
||||||
root.latestVersion = data.version
|
|
||||||
}
|
|
||||||
if (data.contributors) {
|
|
||||||
root.contributors = data.contributors
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: versionProcess
|
id: versionProcess
|
||||||
|
|
||||||
command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/releases/latest"]
|
command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/releases/latest"]
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(text)
|
const data = JSON.parse(text);
|
||||||
if (data.tag_name) {
|
if (data.tag_name) {
|
||||||
const version = data.tag_name
|
const version = data.tag_name;
|
||||||
githubData.version = version
|
githubData.version = version;
|
||||||
root.latestVersion = version
|
root.latestVersion = version;
|
||||||
console.log("[About] Latest version fetched from GitHub:", version)
|
console.log("[About] Latest version fetched from GitHub:", version);
|
||||||
} else {
|
} else {
|
||||||
console.log("No tag_name in GitHub response")
|
console.log("No tag_name in GitHub response");
|
||||||
}
|
}
|
||||||
saveData()
|
saveData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to parse version:", e)
|
console.error("Failed to parse version:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: contributorsProcess
|
id: contributorsProcess
|
||||||
|
|
||||||
command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/contributors?per_page=100"]
|
command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/contributors?per_page=100"]
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(text)
|
const data = JSON.parse(text);
|
||||||
githubData.contributors = data || []
|
githubData.contributors = data || [];
|
||||||
root.contributors = githubData.contributors
|
root.contributors = githubData.contributors;
|
||||||
console.log("[About] Contributors data fetched from GitHub:", githubData.contributors.length, "contributors")
|
console.log("[About] Contributors data fetched from GitHub:", githubData.contributors.length, "contributors");
|
||||||
saveData()
|
saveData();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to parse contributors:", e)
|
console.error("Failed to parse contributors:", e);
|
||||||
root.contributors = []
|
root.contributors = [];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchFromGitHub() {
|
|
||||||
versionProcess.running = true
|
|
||||||
contributorsProcess.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveData() {
|
|
||||||
githubData.timestamp = Date.now()
|
|
||||||
Qt.callLater(() => {
|
|
||||||
githubDataFile.writeAdapter()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -147,7 +160,7 @@ Item {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 16
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|
@ -191,8 +204,8 @@ Item {
|
||||||
color: Theme.textPrimary
|
color: Theme.textPrimary
|
||||||
font.bold: true
|
font.bold: true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
|
@ -204,20 +217,22 @@ Item {
|
||||||
border.color: Theme.accentPrimary
|
border.color: Theme.accentPrimary
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: {
|
visible: {
|
||||||
if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown") {
|
if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown")
|
||||||
return false
|
return false;
|
||||||
}
|
|
||||||
const latest = root.latestVersion.replace("v", "").split(".")
|
|
||||||
const current = root.currentVersion.replace("v", "").split(".")
|
|
||||||
|
|
||||||
|
|
||||||
|
const latest = root.latestVersion.replace("v", "").split(".");
|
||||||
|
const current = root.currentVersion.replace("v", "").split(".");
|
||||||
for (let i = 0; i < Math.max(latest.length, current.length); i++) {
|
for (let i = 0; i < Math.max(latest.length, current.length); i++) {
|
||||||
const l = parseInt(latest[i] || "0")
|
const l = parseInt(latest[i] || "0");
|
||||||
const c = parseInt(current[i] || "0")
|
const c = parseInt(current[i] || "0");
|
||||||
if (l > c) return true
|
if (l > c)
|
||||||
if (l < c) return false
|
return true;
|
||||||
|
|
||||||
|
if (l < c)
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -233,21 +248,25 @@ Item {
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: updateText
|
id: updateText
|
||||||
|
|
||||||
text: "Download latest release"
|
text: "Download latest release"
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary
|
color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: updateArea
|
id: updateArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"])
|
Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|
@ -258,10 +277,17 @@ Item {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 26
|
||||||
|
Layout.bottomMargin: 18
|
||||||
|
height: 1
|
||||||
|
color: Theme.outline
|
||||||
|
opacity: 0.3
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
|
||||||
Layout.leftMargin: 32
|
Layout.leftMargin: 32
|
||||||
Layout.rightMargin: 32
|
Layout.rightMargin: 32
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
|
@ -282,6 +308,7 @@ Item {
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
color: Theme.textSecondary
|
color: Theme.textSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
|
@ -294,11 +321,12 @@ Item {
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
id: contributorsGrid
|
id: contributorsGrid
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: Math.min(parent.width, Math.ceil(root.contributors.length / 3) * 200)
|
width: Math.min(parent.width, Math.ceil(root.contributors.length / 3) * 200)
|
||||||
height: parent.height
|
height: parent.height
|
||||||
cellWidth: 200
|
cellWidth: 200
|
||||||
cellHeight: 110
|
cellHeight: 100
|
||||||
model: root.contributors
|
model: root.contributors
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
|
|
@ -312,7 +340,6 @@ Item {
|
||||||
anchors.margins: 8
|
anchors.margins: 8
|
||||||
spacing: 12
|
spacing: 12
|
||||||
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.preferredWidth: 40
|
Layout.preferredWidth: 40
|
||||||
|
|
@ -320,6 +347,7 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: avatarImage
|
id: avatarImage
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: modelData.avatar_url || ""
|
source: modelData.avatar_url || ""
|
||||||
sourceSize: Qt.size(80, 80)
|
sourceSize: Qt.size(80, 80)
|
||||||
|
|
@ -340,15 +368,17 @@ Item {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: mask
|
id: mask
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
visible: false
|
visible: false
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: avatarImage.width / 2
|
radius: avatarImage.width / 2
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
@ -358,8 +388,8 @@ Item {
|
||||||
color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary
|
color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary
|
||||||
visible: !avatarImage.source || avatarImage.status !== Image.Ready
|
visible: !avatarImage.source || avatarImage.status !== Image.Ready
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
|
|
@ -379,27 +409,36 @@ Item {
|
||||||
font.pixelSize: 11
|
font.pixelSize: 11
|
||||||
color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textSecondary
|
color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: contributorArea
|
id: contributorArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData.html_url) {
|
if (modelData.html_url)
|
||||||
Quickshell.execDetached(["xdg-open", modelData.html_url])
|
Quickshell.execDetached(["xdg-open", modelData.html_url]);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Settings
|
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
import qs.Settings
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 0
|
anchors.margins: 0
|
||||||
|
|
@ -15,7 +16,6 @@ ColumnLayout {
|
||||||
Layout.preferredHeight: 0
|
Layout.preferredHeight: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -28,7 +28,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: 8
|
Layout.bottomMargin: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 2
|
spacing: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -67,7 +66,9 @@ ColumnLayout {
|
||||||
z: 2
|
z: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
Avatar {}
|
Avatar {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -80,6 +81,7 @@ ColumnLayout {
|
||||||
|
|
||||||
TextInput {
|
TextInput {
|
||||||
id: profileImageInput
|
id: profileImageInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: 12
|
anchors.leftMargin: 12
|
||||||
anchors.rightMargin: 12
|
anchors.rightMargin: 12
|
||||||
|
|
@ -96,25 +98,27 @@ ColumnLayout {
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
Settings.settings.profileImage = text;
|
Settings.settings.profileImage = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.IBeamCursor
|
cursorShape: Qt.IBeamCursor
|
||||||
onClicked: profileImageInput.forceActiveFocus()
|
onClicked: profileImageInput.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
Layout.bottomMargin: 18
|
Layout.bottomMargin: 18
|
||||||
anchors {
|
|
||||||
top: headerArea.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: 1
|
height: 1
|
||||||
color: Theme.outline
|
color: Theme.outline
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
|
|
@ -124,7 +128,6 @@ ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "User Interface"
|
text: "User Interface"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
|
|
@ -133,7 +136,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: 8
|
Layout.bottomMargin: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -160,10 +162,12 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: cornersSwitch
|
id: cornersSwitch
|
||||||
|
|
||||||
width: 52
|
width: 52
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -173,6 +177,7 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: cornersThumb
|
id: cornersThumb
|
||||||
|
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
|
|
@ -187,7 +192,9 @@ ColumnLayout {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -197,10 +204,12 @@ ColumnLayout {
|
||||||
Settings.settings.showCorners = !Settings.settings.showCorners;
|
Settings.settings.showCorners = !Settings.settings.showCorners;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
@ -229,10 +238,12 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: dockSwitch
|
id: dockSwitch
|
||||||
|
|
||||||
width: 52
|
width: 52
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -242,6 +253,7 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: dockThumb
|
id: dockThumb
|
||||||
|
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
|
|
@ -256,7 +268,9 @@ ColumnLayout {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -266,10 +280,12 @@ ColumnLayout {
|
||||||
Settings.settings.showDock = !Settings.settings.showDock;
|
Settings.settings.showDock = !Settings.settings.showDock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
@ -298,10 +314,12 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: dimSwitch
|
id: dimSwitch
|
||||||
|
|
||||||
width: 52
|
width: 52
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -311,6 +329,7 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: dimThumb
|
id: dimThumb
|
||||||
|
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
|
|
@ -325,7 +344,9 @@ ColumnLayout {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -335,13 +356,18 @@ ColumnLayout {
|
||||||
Settings.settings.dimPanels = !Settings.settings.dimPanels;
|
Settings.settings.dimPanels = !Settings.settings.dimPanels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -98,19 +98,14 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
Layout.bottomMargin: 18
|
Layout.bottomMargin: 18
|
||||||
anchors {
|
|
||||||
top: headerArea.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: 1
|
height: 1
|
||||||
color: Theme.outline
|
color: Theme.outline
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 16
|
spacing: 16
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Settings
|
|
||||||
import qs.Components
|
import qs.Components
|
||||||
|
import qs.Settings
|
||||||
import qs.Widgets.SettingsWindow.Tabs.Components
|
import qs.Widgets.SettingsWindow.Tabs.Components
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 0
|
anchors.margins: 0
|
||||||
|
|
@ -16,7 +17,6 @@ ColumnLayout {
|
||||||
Layout.preferredHeight: 0
|
Layout.preferredHeight: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -29,7 +29,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: 8
|
Layout.bottomMargin: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -57,10 +56,12 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: use12HourClockSwitch
|
id: use12HourClockSwitch
|
||||||
|
|
||||||
width: 52
|
width: 52
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -70,6 +71,7 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: use12HourClockThumb
|
id: use12HourClockThumb
|
||||||
|
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
|
|
@ -84,7 +86,9 @@ ColumnLayout {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -94,10 +98,12 @@ ColumnLayout {
|
||||||
Settings.settings.use12HourClock = !Settings.settings.use12HourClock;
|
Settings.settings.use12HourClock = !Settings.settings.use12HourClock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
@ -126,10 +132,12 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: reverseDayMonthSwitch
|
id: reverseDayMonthSwitch
|
||||||
|
|
||||||
width: 52
|
width: 52
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -139,6 +147,7 @@ ColumnLayout {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: reverseDayMonthThumb
|
id: reverseDayMonthThumb
|
||||||
|
|
||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
|
|
@ -153,7 +162,9 @@ ColumnLayout {
|
||||||
duration: 200
|
duration: 200
|
||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -163,25 +174,24 @@ ColumnLayout {
|
||||||
Settings.settings.reverseDayMonth = !Settings.settings.reverseDayMonth;
|
Settings.settings.reverseDayMonth = !Settings.settings.reverseDayMonth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
Layout.bottomMargin: 18
|
Layout.bottomMargin: 18
|
||||||
anchors {
|
|
||||||
top: headerArea.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: 1
|
height: 1
|
||||||
color: Theme.outline
|
color: Theme.outline
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -194,7 +204,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: 8
|
Layout.bottomMargin: 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -223,6 +232,7 @@ ColumnLayout {
|
||||||
|
|
||||||
TextInput {
|
TextInput {
|
||||||
id: cityInput
|
id: cityInput
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: 12
|
anchors.leftMargin: 12
|
||||||
anchors.rightMargin: 12
|
anchors.rightMargin: 12
|
||||||
|
|
@ -237,7 +247,6 @@ ColumnLayout {
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
inputMethodHints: Qt.ImhNone
|
inputMethodHints: Qt.ImhNone
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
Settings.settings.weatherCity = text;
|
Settings.settings.weatherCity = text;
|
||||||
}
|
}
|
||||||
|
|
@ -249,10 +258,12 @@ ColumnLayout {
|
||||||
cityInput.forceActiveFocus();
|
cityInput.forceActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
@ -281,15 +292,21 @@ ColumnLayout {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UnitSelector {}
|
UnitSelector {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -122,16 +122,15 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
Layout.bottomMargin: 18
|
Layout.bottomMargin: 18
|
||||||
anchors {
|
|
||||||
top: headerArea.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: 1
|
height: 1
|
||||||
color: Theme.outline
|
color: Theme.outline
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
|
|
@ -388,16 +387,10 @@ ColumnLayout {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
Layout.bottomMargin: 18
|
Layout.bottomMargin: 18
|
||||||
anchors {
|
|
||||||
top: headerArea.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
height: 1
|
height: 1
|
||||||
color: Theme.outline
|
color: Theme.outline
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue