Settings: large cleanup and factorization. Should look much better.
This commit is contained in:
parent
1206be34dc
commit
8302285388
21 changed files with 2434 additions and 2937 deletions
|
|
@ -175,7 +175,7 @@ NPanel {
|
||||||
// Action buttons
|
// Action buttons
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginL * scaling
|
||||||
|
|
||||||
NIconButton {
|
NIconButton {
|
||||||
icon: "refresh"
|
icon: "refresh"
|
||||||
|
|
@ -187,7 +187,6 @@ NPanel {
|
||||||
colorBg: Color.mSurfaceVariant
|
colorBg: Color.mSurfaceVariant
|
||||||
colorFg: Color.mOnSurface
|
colorFg: Color.mOnSurface
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 35 * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NIconButton {
|
NIconButton {
|
||||||
|
|
@ -201,7 +200,6 @@ NPanel {
|
||||||
colorBg: ArchUpdaterService.updateInProgress ? Color.mSurfaceVariant : Color.mPrimary
|
colorBg: ArchUpdaterService.updateInProgress ? Color.mSurfaceVariant : Color.mPrimary
|
||||||
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : Color.mOnPrimary
|
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : Color.mOnPrimary
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 35 * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NIconButton {
|
NIconButton {
|
||||||
|
|
@ -219,7 +217,6 @@ NPanel {
|
||||||
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : (ArchUpdaterService.selectedPackagesCount
|
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : (ArchUpdaterService.selectedPackagesCount
|
||||||
> 0 ? Color.mOnSecondary : Color.mOnSurfaceVariant)
|
> 0 ? Color.mOnSecondary : Color.mOnSurfaceVariant)
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 35 * scaling
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ NPanel {
|
||||||
// Tab label on the main right side
|
// Tab label on the main right side
|
||||||
NText {
|
NText {
|
||||||
text: root.tabsModel[currentTabIndex].label
|
text: root.tabsModel[currentTabIndex].label
|
||||||
font.pointSize: Style.fontSizeL * scaling
|
font.pointSize: Style.fontSizeXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mPrimary
|
color: Color.mPrimary
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -287,21 +287,28 @@ NPanel {
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
clip: true
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.tabsModel
|
model: root.tabsModel
|
||||||
|
|
||||||
onItemAdded: function (index, item) {
|
|
||||||
item.sourceComponent = root.tabsModel[index].source
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: Loader {
|
delegate: Loader {
|
||||||
// All loaders will occupy the same space, stacked on top of each other.
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: index === root.currentTabIndex
|
active: index === root.currentTabIndex
|
||||||
// The loader is only active (and uses memory) when its page is visible.
|
sourceComponent: ColumnLayout {
|
||||||
active: visible
|
ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||||
|
padding: Style.marginL * scaling
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: true
|
||||||
|
sourceComponent: root.tabsModel[index].source
|
||||||
|
width: scrollView.availableWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,6 @@ ColumnLayout {
|
||||||
property string currentVersion: "Unknown" // Fallback version
|
property string currentVersion: "Unknown" // Fallback version
|
||||||
property var contributors: GitHubService.contributors
|
property var contributors: GitHubService.contributors
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: currentVersionProcess
|
id: currentVersionProcess
|
||||||
|
|
||||||
|
|
@ -41,23 +37,9 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginL * scaling
|
|
||||||
rightPadding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Noctalia: quiet by design"
|
text: "Noctalia Shell"
|
||||||
font.pointSize: Style.fontSizeXXXL * scaling
|
font.pointSize: Style.fontSizeXXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurface
|
||||||
|
|
@ -65,14 +47,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "It may just be another quickshell setup but it won't get in your way."
|
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
columns: 2
|
columns: 2
|
||||||
|
|
@ -163,8 +137,8 @@ ColumnLayout {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginxL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
|
|
@ -258,5 +232,4 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
property real localVolume: AudioService.volume
|
property real localVolume: AudioService.volume
|
||||||
|
|
||||||
// Connection used to open the pill when volume changes
|
|
||||||
Connections {
|
Connections {
|
||||||
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
|
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
|
||||||
function onVolumeChanged() {
|
function onVolumeChanged() {
|
||||||
|
|
@ -19,52 +16,13 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Audio Output Volume"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volume Controls
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginS * scaling
|
|
||||||
|
|
||||||
// Master Volume
|
// Master Volume
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NLabel {
|
NLabel {
|
||||||
label: "Master Volume"
|
label: "Output Volume"
|
||||||
description: "System-wide volume level."
|
description: "System-wide volume level."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,24 +99,22 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioService Devices
|
// AudioService Devices
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Audio Devices"
|
text: "Audio Devices"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,7 +145,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// Input Devices
|
// Input Devices
|
||||||
|
|
@ -223,25 +178,44 @@ ColumnLayout {
|
||||||
// Divider
|
// Divider
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginXL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// MPRIS Player Preferences
|
// Media Player Preferences
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "MPRIS Player Preferences"
|
text: "Media Player"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Miniplayer section
|
||||||
|
NToggle {
|
||||||
|
label: "Show Album Art In Bar Media Player"
|
||||||
|
description: "Show the album art of the currently playing song next to the title."
|
||||||
|
checked: Settings.data.audio.showMiniplayerAlbumArt
|
||||||
|
onToggled: checked => {
|
||||||
|
Settings.data.audio.showMiniplayerAlbumArt = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
label: "Show Audio Visualizer In Bar Media Player"
|
||||||
|
description: "Shows an audio visualizer in the background of the miniplayer."
|
||||||
|
checked: Settings.data.audio.showMiniplayerCava
|
||||||
|
onToggled: checked => {
|
||||||
|
Settings.data.audio.showMiniplayerCava = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
// Preferred player (persistent)
|
// Preferred player (persistent)
|
||||||
NTextInput {
|
NTextInput {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
label: "Preferred Player"
|
label: "Preferred Player"
|
||||||
description: "Substring to match MPRIS player (identity/bus/desktop)."
|
description: "Substring to match MPRIS player (identity/bus/desktop)."
|
||||||
placeholderText: "e.g. spotify, vlc, mpv"
|
placeholderText: "e.g. spotify, vlc, mpv"
|
||||||
|
|
@ -266,7 +240,7 @@ ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
label: "Blacklist player"
|
label: "Blacklist player"
|
||||||
description: "Substring, e.g. plex, shim, mpv"
|
description: "Substring, e.g. plex, shim, mpv."
|
||||||
placeholderText: "type substring and press +"
|
placeholderText: "type substring and press +"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,46 +329,6 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: Style.marginXL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bar Mini Media player
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginL * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Bar Media Player"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Miniplayer section
|
|
||||||
NToggle {
|
|
||||||
label: "Show Album Art In Bar Media Player"
|
|
||||||
description: "Show the album art of the currently playing song next to the title."
|
|
||||||
checked: Settings.data.audio.showMiniplayerAlbumArt
|
|
||||||
onToggled: checked => {
|
|
||||||
Settings.data.audio.showMiniplayerAlbumArt = checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NToggle {
|
|
||||||
label: "Show Audio Visualizer In Bar Media Player"
|
|
||||||
description: "Shows an audio visualizer in the background of the miniplayer."
|
|
||||||
checked: Settings.data.audio.showMiniplayerCava
|
|
||||||
onToggled: checked => {
|
|
||||||
Settings.data.audio.showMiniplayerCava = checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Divider
|
|
||||||
NDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginXL * scaling
|
|
||||||
Layout.bottomMargin: Style.marginXL * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// AudioService Visualizer Category
|
// AudioService Visualizer Category
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
|
|
@ -404,7 +338,7 @@ ColumnLayout {
|
||||||
text: "Audio Visualizer"
|
text: "Audio Visualizer"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +373,7 @@ ColumnLayout {
|
||||||
|
|
||||||
NComboBox {
|
NComboBox {
|
||||||
label: "Frame Rate"
|
label: "Frame Rate"
|
||||||
description: "Target frame rate for audio visualizer. (default: 60)"
|
description: "Target frame rate for audio visualizer."
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
key: "30"
|
key: "30"
|
||||||
|
|
@ -476,6 +410,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// Divider
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,54 +6,15 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Bar Position"
|
|
||||||
font.pointSize: Style.fontSizeL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Choose where to place the bar on the screen"
|
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
NComboBox {
|
NComboBox {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
label: "Bar Position"
|
||||||
|
description: "Choose where to place the bar on the screen."
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
key: "top"
|
key: "top"
|
||||||
|
|
@ -65,9 +26,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentKey: Settings.data.bar.position
|
currentKey: Settings.data.bar.position
|
||||||
onSelected: key => {
|
onSelected: key => Settings.data.bar.position = key
|
||||||
Settings.data.bar.position = key
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,11 +109,12 @@ ColumnLayout {
|
||||||
Settings.data.bar.showWorkspaceLabel = key
|
Settings.data.bar.showWorkspaceLabel = key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Widgets Management Section
|
// Widgets Management Section
|
||||||
|
|
@ -190,7 +150,6 @@ ColumnLayout {
|
||||||
sectionName: "Left"
|
sectionName: "Left"
|
||||||
widgetModel: Settings.data.bar.widgets.left
|
widgetModel: Settings.data.bar.widgets.left
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
scrollView: scrollView
|
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
|
|
@ -201,7 +160,6 @@ ColumnLayout {
|
||||||
sectionName: "Center"
|
sectionName: "Center"
|
||||||
widgetModel: Settings.data.bar.widgets.center
|
widgetModel: Settings.data.bar.widgets.center
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
scrollView: scrollView
|
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
|
|
@ -212,15 +170,17 @@ ColumnLayout {
|
||||||
sectionName: "Right"
|
sectionName: "Right"
|
||||||
widgetModel: Settings.data.bar.widgets.right
|
widgetModel: Settings.data.bar.widgets.right
|
||||||
availableWidgets: availableWidgets
|
availableWidgets: availableWidgets
|
||||||
scrollView: scrollView
|
|
||||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
|
|
|
||||||
|
|
@ -6,33 +6,11 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
readonly property real scaling: ScalingService.scale(screen)
|
readonly property real scaling: ScalingService.scale(screen)
|
||||||
readonly property string tabIcon: "brightness_6"
|
readonly property string tabIcon: "brightness_6"
|
||||||
readonly property string tabLabel: "Brightness"
|
readonly property string tabLabel: "Brightness"
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
|
||||||
contentWidth: parent.width
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.margins: Style.marginL * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Brightness Settings"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brightness Step Section
|
// Brightness Step Section
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
@ -54,16 +32,9 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginL * scaling
|
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Monitor Overview Section
|
// Monitor Overview Section
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NLabel {
|
NLabel {
|
||||||
label: "Monitors Brightness Control"
|
label: "Monitors Brightness Control"
|
||||||
|
|
@ -147,10 +118,9 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
NDivider {
|
||||||
Layout.fillHeight: true
|
Layout.fillWidth: true
|
||||||
}
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
}
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import qs.Widgets
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
// Helper function to get color from scheme file (supports dark/light variants)
|
// Helper function to get color from scheme file (supports dark/light variants)
|
||||||
function getSchemeColor(schemePath, colorKey) {
|
function getSchemeColor(schemePath, colorKey) {
|
||||||
// Extract scheme name from path
|
// Extract scheme name from path
|
||||||
|
|
@ -55,6 +53,28 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple process to check if matugen exists
|
||||||
|
Process {
|
||||||
|
id: matugenCheck
|
||||||
|
command: ["which", "matugen"]
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onExited: function (exitCode) {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
// Matugen exists, enable it
|
||||||
|
Settings.data.colorSchemes.useWallpaperColors = true
|
||||||
|
ColorSchemeService.changedWallpaper()
|
||||||
|
ToastService.showNotice("Matugen", "Enabled!")
|
||||||
|
} else {
|
||||||
|
// Matugen not found
|
||||||
|
ToastService.showWarning("Matugen", "Not installed!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout: StdioCollector {}
|
||||||
|
stderr: StdioCollector {}
|
||||||
|
}
|
||||||
|
|
||||||
// A non-visual Item to host the Repeater that loads the color scheme files.
|
// A non-visual Item to host the Repeater that loads the color scheme files.
|
||||||
Item {
|
Item {
|
||||||
visible: false
|
visible: false
|
||||||
|
|
@ -83,17 +103,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI Code
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: scrollView.availableWidth
|
width: scrollView.availableWidth
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
@ -159,36 +168,30 @@ ColumnLayout {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginXXS * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Predefined Color Schemes"
|
text: "Predefined Color Schemes"
|
||||||
font.pointSize: Style.fontSizeL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "These color schemes only apply when 'Use Matugen' is disabled. When enabled, Matugen will generate colors based on your wallpaper instead. You can toggle between light and dark themes when using Matugen."
|
text: "These color schemes are only active when 'Use Matugen' is turned off. With Matugen enabled, colors will be automatically generated from your wallpaper. You can still switch between light and dark themes while using Matugen."
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurfaceVariant
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginL * scaling
|
|
||||||
|
|
||||||
// Color Schemes Grid
|
// Color Schemes Grid
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 4
|
columns: 4
|
||||||
|
|
@ -340,28 +343,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple process to check if matugen exists
|
NDivider {
|
||||||
Process {
|
Layout.fillWidth: true
|
||||||
id: matugenCheck
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
command: ["which", "matugen"]
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
// Matugen exists, enable it
|
|
||||||
Settings.data.colorSchemes.useWallpaperColors = true
|
|
||||||
ColorSchemeService.changedWallpaper()
|
|
||||||
ToastService.showNotice("Matugen", "Enabled!")
|
|
||||||
} else {
|
|
||||||
// Matugen not found
|
|
||||||
ToastService.showWarning("Matugen", "Not installed!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout: StdioCollector {}
|
|
||||||
stderr: StdioCollector {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,11 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
readonly property real scaling: ScalingService.scale(screen)
|
readonly property real scaling: ScalingService.scale(screen)
|
||||||
readonly property string tabIcon: "monitor"
|
readonly property string tabIcon: "monitor"
|
||||||
readonly property string tabLabel: "Display"
|
readonly property string tabLabel: "Display"
|
||||||
readonly property int tabIndex: 5
|
readonly property int tabIndex: 5
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
// Time dropdown options (00:00 .. 23:30)
|
// Time dropdown options (00:00 .. 23:30)
|
||||||
ListModel {
|
ListModel {
|
||||||
|
|
@ -45,38 +43,26 @@ Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
|
||||||
contentWidth: Math.max(parent.width, 600 * scaling)
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: contentColumn
|
|
||||||
width: Math.max(parent.width, 600 * scaling)
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginL * scaling
|
|
||||||
Layout.margins: Style.marginL * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Per‑monitor configuration"
|
text: "Monitor-specific configuration"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "By default, bars and notifications are shown on all displays. Select one or more below to narrow your view."
|
text: "Bars and notifications appear on all displays by default. Choose specific displays below to limit where they're shown."
|
||||||
font.pointSize: Style.fontSize * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
color: Color.mOnSurfaceVariant
|
color: Color.mOnSurfaceVariant
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginL * scaling
|
||||||
|
Layout.topMargin: Style.marginL * scaling
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Quickshell.screens || []
|
model: Quickshell.screens || []
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
|
|
@ -134,8 +120,8 @@ Item {
|
||||||
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
|
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
Settings.data.notifications.monitors = addMonitor(
|
Settings.data.notifications.monitors = addMonitor(Settings.data.notifications.monitors,
|
||||||
Settings.data.notifications.monitors, modelData.name)
|
modelData.name)
|
||||||
} else {
|
} else {
|
||||||
Settings.data.notifications.monitors = removeMonitor(
|
Settings.data.notifications.monitors = removeMonitor(
|
||||||
Settings.data.notifications.monitors, modelData.name)
|
Settings.data.notifications.monitors, modelData.name)
|
||||||
|
|
@ -152,8 +138,7 @@ Item {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
Settings.data.dock.monitors = addMonitor(Settings.data.dock.monitors, modelData.name)
|
Settings.data.dock.monitors = addMonitor(Settings.data.dock.monitors, modelData.name)
|
||||||
} else {
|
} else {
|
||||||
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors,
|
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors, modelData.name)
|
||||||
modelData.name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,67 +213,54 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
|
}
|
||||||
|
|
||||||
// Night Light Section
|
// Night Light Section
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXS * scaling
|
||||||
NText {
|
NText {
|
||||||
text: "Night Light"
|
text: "Night Light"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.topMargin: Style.marginXL * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Reduce blue light emission to help you sleep better and reduce eye strain."
|
text: "Reduce blue light emission to help you sleep better and reduce eye strain."
|
||||||
font.pointSize: Style.fontSize * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
color: Color.mOnSurfaceVariant
|
color: Color.mOnSurfaceVariant
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "Enable Night Light"
|
label: "Enable Night Light"
|
||||||
description: "Apply a warm color filter to reduce blue light emission."
|
description: "Apply a warm color filter to reduce blue light emission."
|
||||||
checked: Settings.data.nightLight.enabled
|
checked: Settings.data.nightLight.enabled
|
||||||
onToggled: checked => {
|
onToggled: checked => Settings.data.nightLight.enabled = checked
|
||||||
Settings.data.nightLight.enabled = checked
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "Auto Schedule"
|
label: "Auto Schedule"
|
||||||
description: "Automatically enable night light based on time schedule."
|
description: "Automatically enable night light based on time schedule."
|
||||||
checked: Settings.data.nightLight.autoSchedule
|
checked: Settings.data.nightLight.autoSchedule
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intensity settings
|
// Intensity settings
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginXS * scaling
|
NLabel {
|
||||||
|
label: "Intensity"
|
||||||
NText {
|
description: "Higher values create warmer light."
|
||||||
text: "Intensity"
|
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Higher values create warmer (more orange) light, lower values create cooler (more blue) light."
|
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
|
|
||||||
NSlider {
|
NSlider {
|
||||||
from: 0
|
from: 0
|
||||||
|
|
@ -307,31 +279,24 @@ Item {
|
||||||
horizontalAlignment: Text.AlignRight
|
horizontalAlignment: Text.AlignRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Schedule settings
|
// Schedule settings
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginXS * scaling
|
spacing: Style.marginXS * scaling
|
||||||
|
|
||||||
NText {
|
NLabel {
|
||||||
text: "Schedule"
|
label: "Schedule"
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
description: "Set a start and end time for automatic schedule."
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: Style.marginL * scaling
|
Layout.fillWidth: false
|
||||||
Layout.fillWidth: true
|
spacing: Style.marginM * scaling
|
||||||
enabled: Settings.data.nightLight.enabled
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Start Time"
|
text: "Start Time"
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
color: Color.mOnSurfaceVariant
|
color: Color.mOnSurfaceVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,33 +305,32 @@ Item {
|
||||||
currentKey: Settings.data.nightLight.startTime
|
currentKey: Settings.data.nightLight.startTime
|
||||||
placeholder: "Select start time"
|
placeholder: "Select start time"
|
||||||
onSelected: key => Settings.data.nightLight.startTime = key
|
onSelected: key => Settings.data.nightLight.startTime = key
|
||||||
}
|
preferredWidth: 120 * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Item {// add a little more spacing
|
||||||
spacing: Style.marginXXS * scaling
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Stop Time"
|
text: "Stop Time"
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
color: Color.mOnSurfaceVariant
|
color: Color.mOnSurfaceVariant
|
||||||
}
|
}
|
||||||
|
|
||||||
NComboBox {
|
NComboBox {
|
||||||
model: timeOptions
|
model: timeOptions
|
||||||
currentKey: Settings.data.nightLight.stopTime
|
currentKey: Settings.data.nightLight.stopTime
|
||||||
placeholder: "Select stop time"
|
placeholder: "Select stop time"
|
||||||
onSelected: key => Settings.data.nightLight.stopTime = key
|
onSelected: key => Settings.data.nightLight.stopTime = key
|
||||||
|
preferredWidth: 120 * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
NDivider {
|
||||||
}
|
Layout.fillWidth: true
|
||||||
}
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
}
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,46 +6,8 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginL * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "General Settings"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
// Profile section
|
// Profile section
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginS * scaling
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
|
|
@ -71,8 +33,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -80,6 +40,7 @@ ColumnLayout {
|
||||||
Layout.bottomMargin: Style.marginXL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User Interface
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -88,7 +49,7 @@ ColumnLayout {
|
||||||
text: "User Interface"
|
text: "User Interface"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,19 +84,9 @@ ColumnLayout {
|
||||||
spacing: Style.marginXXS * scaling
|
spacing: Style.marginXXS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NText {
|
NLabel {
|
||||||
text: "Border radius"
|
label: "Border radius"
|
||||||
font.pointSize: Style.fontSizeL * scaling
|
description: "Adjust the rounded border of all UI elements."
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Adjust the rounded border of all UI elements"
|
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -158,30 +109,14 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginXL * scaling
|
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animation Speed
|
// Animation Speed
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginXXS * scaling
|
spacing: Style.marginXXS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NText {
|
NLabel {
|
||||||
text: "Animation Speed"
|
label: "Animation Speed"
|
||||||
font.pointSize: Style.fontSizeL * scaling
|
description: "Adjust global animation speed."
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Adjust global animation speed (0.1× to 2.0×)"
|
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -203,18 +138,29 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginL * scaling
|
||||||
|
Layout.fillWidth: true
|
||||||
NText {
|
NText {
|
||||||
text: "Fonts"
|
text: "Fonts"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Font configuration section
|
// Font configuration section
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NTextInput {
|
NTextInput {
|
||||||
|
|
@ -251,6 +197,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,62 +6,9 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Launcher"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NToggle {
|
|
||||||
label: "Enable Clipboard History"
|
|
||||||
description: "Show clipboard history in the Launcher (command >clip)."
|
|
||||||
checked: Settings.data.appLauncher.enableClipboardHistory
|
|
||||||
onToggled: checked => {
|
|
||||||
Settings.data.appLauncher.enableClipboardHistory = checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginL * scaling
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Launcher Position"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
NComboBox {
|
NComboBox {
|
||||||
id: launcherPosition
|
id: launcherPosition
|
||||||
|
|
@ -104,18 +51,32 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDivider {
|
NToggle {
|
||||||
|
label: "Enable Clipboard History"
|
||||||
|
description: "Show clipboard history in the launcher."
|
||||||
|
checked: Settings.data.appLauncher.enableClipboardHistory
|
||||||
|
onToggled: checked => {
|
||||||
|
Settings.data.appLauncher.enableClipboardHistory = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXXS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * scaling
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
NText {
|
||||||
|
text: "Background Opacity"
|
||||||
|
font.pointSize: Style.fontSizeL * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Launcher Background"
|
text: "Adjust the background opacity of the launcher."
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXS * scaling
|
||||||
font.weight: Style.fontWeightBold
|
color: Color.mOnSurfaceVariant
|
||||||
color: Color.mOnSurface
|
wrapMode: Text.WordWrap
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -139,5 +100,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,39 +7,8 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: root
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Interfaces"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "WiFi Enabled"
|
label: "WiFi Enabled"
|
||||||
|
|
@ -70,7 +39,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,40 +6,7 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
spacing: Style.marginL * scaling
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Recordings"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output Directory
|
// Output Directory
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
@ -55,6 +22,7 @@ ColumnLayout {
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
Settings.data.screenRecorder.directory = text
|
Settings.data.screenRecorder.directory = text
|
||||||
}
|
}
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
@ -75,8 +43,8 @@ ColumnLayout {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Video Settings
|
// Video Settings
|
||||||
|
|
@ -88,7 +56,7 @@ ColumnLayout {
|
||||||
text: "Video Settings"
|
text: "Video Settings"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +83,7 @@ ColumnLayout {
|
||||||
// Frame Rate
|
// Frame Rate
|
||||||
NComboBox {
|
NComboBox {
|
||||||
label: "Frame Rate"
|
label: "Frame Rate"
|
||||||
description: "Target frame rate for screen recordings. (default: 60)"
|
description: "Target frame rate for screen recordings."
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
key: "30"
|
key: "30"
|
||||||
|
|
@ -248,7 +216,7 @@ ColumnLayout {
|
||||||
text: "Audio Settings"
|
text: "Audio Settings"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
Layout.bottomMargin: Style.marginS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,7 +264,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,47 +6,8 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
padding: Style.marginM * scaling
|
|
||||||
clip: true
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginXS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Location"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location section
|
// Location section
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginM * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginS * scaling
|
|
||||||
|
|
||||||
NTextInput {
|
NTextInput {
|
||||||
label: "Location name"
|
label: "Location name"
|
||||||
description: "Choose a known location near you."
|
description: "Choose a known location near you."
|
||||||
|
|
@ -58,12 +19,11 @@ ColumnLayout {
|
||||||
LocationService.resetWeather()
|
LocationService.resetWeather()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time section
|
// Time section
|
||||||
|
|
@ -75,8 +35,7 @@ ColumnLayout {
|
||||||
text: "Time Format"
|
text: "Time Format"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
|
|
@ -109,8 +68,8 @@ ColumnLayout {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weather section
|
// Weather section
|
||||||
|
|
@ -122,8 +81,7 @@ ColumnLayout {
|
||||||
text: "Weather"
|
text: "Weather"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
|
|
@ -135,7 +93,10 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,34 +6,20 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
ColumnLayout {
|
||||||
readonly property real scaling: ScalingService.scale(screen)
|
readonly property real scaling: ScalingService.scale(screen)
|
||||||
readonly property string tabIcon: "photo_library"
|
readonly property string tabIcon: "photo_library"
|
||||||
readonly property string tabLabel: "Wallpaper Selector"
|
readonly property string tabLabel: "Wallpaper Selector"
|
||||||
readonly property int tabIndex: 7
|
readonly property int tabIndex: 7
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
|
||||||
contentWidth: parent.width
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.margins: Style.marginL * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
// Current wallpaper display
|
// Current wallpaper display
|
||||||
NText {
|
NText {
|
||||||
text: "Current Wallpaper"
|
text: "Current Wallpaper"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -54,10 +40,11 @@ Item {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wallpaper selector
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
|
@ -69,12 +56,12 @@ Item {
|
||||||
text: "Wallpaper Selector"
|
text: "Wallpaper Selector"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
}
|
}
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "Click on a wallpaper to set it as your current wallpaper."
|
text: "Click on a wallpaper to set it as your current wallpaper."
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurfaceVariant
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
@ -102,8 +89,7 @@ Item {
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: {
|
Layout.preferredHeight: {
|
||||||
return Math.ceil(
|
return Math.ceil(WallpaperService.wallpaperList.length / wallpaperGridView.columns) * wallpaperGridView.cellHeight
|
||||||
WallpaperService.wallpaperList.length / wallpaperGridView.columns) * wallpaperGridView.cellHeight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
|
|
@ -117,8 +103,7 @@ Item {
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
property int columns: 5
|
property int columns: 5
|
||||||
property int itemSize: Math.floor(
|
property int itemSize: Math.floor((width - leftMargin - rightMargin - (4 * Style.marginS * scaling)) / columns)
|
||||||
(width - leftMargin - rightMargin - (4 * Style.marginS * scaling)) / columns)
|
|
||||||
|
|
||||||
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
|
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
|
||||||
cellHeight: Math.floor(itemSize * 0.67) + Style.marginS * scaling
|
cellHeight: Math.floor(itemSize * 0.67) + Style.marginS * scaling
|
||||||
|
|
@ -151,19 +136,19 @@ Item {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Color.transparent
|
color: Color.transparent
|
||||||
border.color: isSelected ? Color.mPrimary : Color.mSurface
|
border.color: isSelected ? Color.mSecondary : Color.mSurface
|
||||||
border.width: Math.max(1, Style.borderL * scaling)
|
border.width: Math.max(1, Style.borderL * 1.5 * scaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selection tick-mark
|
// Selection tick-mark
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: Style.marginXS * scaling
|
anchors.margins: Style.marginS * scaling
|
||||||
width: 28 * scaling
|
width: 28 * scaling
|
||||||
height: 28 * scaling
|
height: 28 * scaling
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
color: Color.mPrimary
|
color: Color.mSecondary
|
||||||
border.color: Color.mOutline
|
border.color: Color.mOutline
|
||||||
border.width: Math.max(1, Style.borderS * scaling)
|
border.width: Math.max(1, Style.borderS * scaling)
|
||||||
visible: isSelected
|
visible: isSelected
|
||||||
|
|
@ -172,7 +157,7 @@ Item {
|
||||||
text: "check"
|
text: "check"
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnPrimary
|
color: Color.mOnSecondary
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -180,8 +165,8 @@ Item {
|
||||||
// Hover effect
|
// Hover effect
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Color.mOnSurface
|
color: Color.mSurface
|
||||||
opacity: mouseArea.containsMouse ? 0.1 : 0
|
opacity: (mouseArea.containsMouse || isSelected) ? 0 : 0.4
|
||||||
radius: parent.radius
|
radius: parent.radius
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
|
|
@ -240,7 +225,10 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
NDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,52 +7,29 @@ import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 0
|
// Process to check if swww is installed
|
||||||
|
Process {
|
||||||
|
id: swwwCheck
|
||||||
|
command: ["which", "swww"]
|
||||||
|
running: false
|
||||||
|
|
||||||
ScrollView {
|
onExited: function (exitCode) {
|
||||||
id: scrollView
|
if (exitCode === 0) {
|
||||||
|
// SWWW exists, enable it
|
||||||
Layout.fillWidth: true
|
Settings.data.wallpaper.swww.enabled = true
|
||||||
Layout.fillHeight: true
|
WallpaperService.startSWWWDaemon()
|
||||||
padding: Style.marginM * scaling
|
ToastService.showNotice("SWWW", "Enabled!")
|
||||||
clip: true
|
} else {
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
// SWWW not found
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
ToastService.showWarning("SWWW", "Not installed!")
|
||||||
|
}
|
||||||
ColumnLayout {
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
stdout: StdioCollector {}
|
||||||
spacing: Style.marginL * scaling
|
stderr: StdioCollector {}
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: "Directory"
|
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wallpaper Settings Category
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: Style.marginS * scaling
|
|
||||||
|
|
||||||
// Wallpaper Folder
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Style.marginS * scaling
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
NTextInput {
|
NTextInput {
|
||||||
label: "Wallpaper Directory"
|
label: "Wallpaper Directory"
|
||||||
description: "Path to your wallpaper directory."
|
description: "Path to your wallpaper directory."
|
||||||
|
|
@ -62,14 +39,11 @@ ColumnLayout {
|
||||||
Settings.data.wallpaper.directory = text
|
Settings.data.wallpaper.directory = text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
@ -80,8 +54,7 @@ ColumnLayout {
|
||||||
text: "Automation"
|
text: "Automation"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random Wallpaper
|
// Random Wallpaper
|
||||||
|
|
@ -306,10 +279,11 @@ ColumnLayout {
|
||||||
id: customRow
|
id: customRow
|
||||||
visible: presetRow.customForcedVisible || !presetRow.isCurrentPreset
|
visible: presetRow.customForcedVisible || !presetRow.isCurrentPreset
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
|
Layout.topMargin: Style.marginS * scaling
|
||||||
|
|
||||||
NTextInput {
|
NTextInput {
|
||||||
label: "Custom Interval"
|
label: "Custom Interval"
|
||||||
description: "Enter time as HH:MM (e.g., 1:30)"
|
description: "Enter time as HH:MM (e.g., 1:30)."
|
||||||
text: {
|
text: {
|
||||||
const s = Settings.data.wallpaper.randomInterval
|
const s = Settings.data.wallpaper.randomInterval
|
||||||
const h = Math.floor(s / 3600)
|
const h = Math.floor(s / 3600)
|
||||||
|
|
@ -339,28 +313,27 @@ ColumnLayout {
|
||||||
|
|
||||||
NDivider {
|
NDivider {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.marginL * 2 * scaling
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
Layout.bottomMargin: Style.marginL * scaling
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// SWWW
|
// Swww
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: Style.marginL * scaling
|
spacing: Style.marginL * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: "SWWW"
|
text: "Swww"
|
||||||
font.pointSize: Style.fontSizeXXL * scaling
|
font.pointSize: Style.fontSizeXXL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mSecondary
|
||||||
Layout.bottomMargin: Style.marginS * scaling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use SWWW
|
// Use SWWW
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "Use SWWW"
|
label: "Use Swww"
|
||||||
description: "Use SWWW daemon for advanced wallpaper management."
|
description: "Use Swww daemon for advanced wallpaper management."
|
||||||
checked: Settings.data.wallpaper.swww.enabled
|
checked: Settings.data.wallpaper.swww.enabled
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
@ -368,7 +341,7 @@ ColumnLayout {
|
||||||
swwwCheck.running = true
|
swwwCheck.running = true
|
||||||
} else {
|
} else {
|
||||||
Settings.data.wallpaper.swww.enabled = false
|
Settings.data.wallpaper.swww.enabled = false
|
||||||
ToastService.showNotice("SWWW", "Disabled")
|
ToastService.showNotice("Swww", "Disabled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +356,7 @@ ColumnLayout {
|
||||||
// Resize Mode
|
// Resize Mode
|
||||||
NComboBox {
|
NComboBox {
|
||||||
label: "Resize Mode"
|
label: "Resize Mode"
|
||||||
description: "How SWWW should resize wallpapers to fit the screen."
|
description: "How Swww should resize wallpapers to fit the screen."
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
key: "no"
|
key: "no"
|
||||||
|
|
@ -478,32 +451,14 @@ ColumnLayout {
|
||||||
|
|
||||||
// Transition FPS
|
// Transition FPS
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
NLabel {
|
||||||
|
label: "Transition FPS"
|
||||||
|
description: "Frames per second for transition animations."
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
spacing: Style.marginL * scaling
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
NText {
|
|
||||||
text: "Transition FPS"
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
NText {
|
|
||||||
text: "Frames per second for transition animations."
|
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
|
||||||
color: Color.mOnSurface
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: sliderWpTransitionFps.value + " FPS"
|
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NSlider {
|
NSlider {
|
||||||
id: sliderWpTransitionFps
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 30
|
from: 30
|
||||||
to: 500
|
to: 500
|
||||||
|
|
@ -512,36 +467,23 @@ ColumnLayout {
|
||||||
onMoved: Settings.data.wallpaper.swww.transitionFps = Math.round(value)
|
onMoved: Settings.data.wallpaper.swww.transitionFps = Math.round(value)
|
||||||
cutoutColor: Color.mSurface
|
cutoutColor: Color.mSurface
|
||||||
}
|
}
|
||||||
|
NText {
|
||||||
|
text: Settings.data.wallpaper.swww.transitionFps + " FPS"
|
||||||
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition Duration
|
// Transition Duration
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
NLabel {
|
||||||
|
label: "Transition Duration"
|
||||||
|
description: "Duration of transition animations in seconds."
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
spacing: Style.marginL * scaling
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
NText {
|
|
||||||
text: "Transition Duration"
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
NText {
|
|
||||||
text: "Duration of transition animations in seconds."
|
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
|
||||||
color: Color.mOnSurface
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: sliderWpTransitionDuration.value.toFixed(2) + "s"
|
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NSlider {
|
NSlider {
|
||||||
id: sliderWpTransitionDuration
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
from: 0.25
|
from: 0.25
|
||||||
to: 10
|
to: 10
|
||||||
|
|
@ -550,31 +492,18 @@ ColumnLayout {
|
||||||
onMoved: Settings.data.wallpaper.swww.transitionDuration = value
|
onMoved: Settings.data.wallpaper.swww.transitionDuration = value
|
||||||
cutoutColor: Color.mSurface
|
cutoutColor: Color.mSurface
|
||||||
}
|
}
|
||||||
|
NText {
|
||||||
|
text: Settings.data.wallpaper.swww.transitionDuration.toFixed(2) + "s"
|
||||||
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process to check if swww is installed
|
NDivider {
|
||||||
Process {
|
Layout.fillWidth: true
|
||||||
id: swwwCheck
|
Layout.topMargin: Style.marginXL * scaling
|
||||||
command: ["which", "swww"]
|
Layout.bottomMargin: Style.marginXL * scaling
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
// SWWW exists, enable it
|
|
||||||
Settings.data.wallpaper.swww.enabled = true
|
|
||||||
WallpaperService.startSWWWDaemon()
|
|
||||||
ToastService.showNotice("SWWW", "Enabled!")
|
|
||||||
} else {
|
|
||||||
// SWWW not found
|
|
||||||
ToastService.showWarning("SWWW", "Not installed!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout: StdioCollector {}
|
|
||||||
stderr: StdioCollector {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property real preferredHeight: Style.baseWidgetSize * 1.35 * scaling
|
readonly property real preferredHeight: Style.baseWidgetSize * 1.1 * scaling
|
||||||
|
property real preferredWidth: 320 * scaling
|
||||||
|
|
||||||
property string label: ""
|
property string label: ""
|
||||||
property string description: ""
|
property string description: ""
|
||||||
|
|
@ -23,11 +24,6 @@ ColumnLayout {
|
||||||
spacing: Style.marginS * scaling
|
spacing: Style.marginS * scaling
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
NLabel {
|
|
||||||
label: root.label
|
|
||||||
description: root.description
|
|
||||||
}
|
|
||||||
|
|
||||||
function findIndexByKey(key) {
|
function findIndexByKey(key) {
|
||||||
for (var i = 0; i < root.model.count; i++) {
|
for (var i = 0; i < root.model.count; i++) {
|
||||||
if (root.model.get(i).key === key) {
|
if (root.model.get(i).key === key) {
|
||||||
|
|
@ -37,10 +33,15 @@ ColumnLayout {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NLabel {
|
||||||
|
label: root.label
|
||||||
|
description: root.description
|
||||||
|
}
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: combo
|
id: combo
|
||||||
|
|
||||||
Layout.preferredWidth: 320 * scaling
|
Layout.preferredWidth: root.preferredWidth
|
||||||
Layout.preferredHeight: height
|
Layout.preferredHeight: height
|
||||||
model: model
|
model: model
|
||||||
currentIndex: findIndexByKey(currentKey)
|
currentIndex: findIndexByKey(currentKey)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ ColumnLayout {
|
||||||
|
|
||||||
NText {
|
NText {
|
||||||
text: label
|
text: label
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
font.pointSize: Style.fontSizeL * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurface
|
||||||
visible: label !== ""
|
visible: label !== ""
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ NBox {
|
||||||
property string sectionName: ""
|
property string sectionName: ""
|
||||||
property var widgetModel: []
|
property var widgetModel: []
|
||||||
property var availableWidgets: []
|
property var availableWidgets: []
|
||||||
property var scrollView: null
|
|
||||||
|
|
||||||
signal addWidget(string widgetName, string section)
|
signal addWidget(string widgetName, string section)
|
||||||
signal removeWidget(string section, int index)
|
signal removeWidget(string section, int index)
|
||||||
|
|
@ -23,7 +22,7 @@ NBox {
|
||||||
if (widgetCount === 0)
|
if (widgetCount === 0)
|
||||||
return 140 * scaling
|
return 140 * scaling
|
||||||
|
|
||||||
var availableWidth = scrollView ? scrollView.availableWidth - (Style.marginM * scaling * 2) : 400 * scaling
|
var availableWidth = parent.width
|
||||||
var avgWidgetWidth = 150 * scaling
|
var avgWidgetWidth = 150 * scaling
|
||||||
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
|
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
|
||||||
var rows = Math.ceil(widgetCount / widgetsPerRow)
|
var rows = Math.ceil(widgetCount / widgetsPerRow)
|
||||||
|
|
@ -52,7 +51,7 @@ NBox {
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Style.marginM * scaling
|
anchors.margins: Style.marginL * scaling
|
||||||
spacing: Style.marginM * scaling
|
spacing: Style.marginM * scaling
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -189,13 +188,13 @@ NBox {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.log("NSectionEditor", `Started dragging widget: ${modelData} at index ${index}`)
|
//Logger.log("NSectionEditor", `Started dragging widget: ${modelData} at index ${index}`)
|
||||||
// Bring to front when starting drag
|
// Bring to front when starting drag
|
||||||
widgetItem.z = 1000
|
widgetItem.z = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
onReleased: {
|
onReleased: {
|
||||||
Logger.log("NSectionEditor", `Released widget: ${modelData} at index ${index}`)
|
//Logger.log("NSectionEditor", `Released widget: ${modelData} at index ${index}`)
|
||||||
// Reset z-index when drag ends
|
// Reset z-index when drag ends
|
||||||
widgetItem.z = 0
|
widgetItem.z = 0
|
||||||
|
|
||||||
|
|
@ -232,13 +231,13 @@ NBox {
|
||||||
if (targetIndex !== -1 && targetIndex !== index) {
|
if (targetIndex !== -1 && targetIndex !== index) {
|
||||||
const fromIndex = index
|
const fromIndex = index
|
||||||
const toIndex = targetIndex
|
const toIndex = targetIndex
|
||||||
Logger.log(
|
// Logger.log(
|
||||||
"NSectionEditor",
|
// "NSectionEditor",
|
||||||
`Dropped widget from index ${fromIndex} to position ${toIndex} (distance: ${minDistance.toFixed(
|
// `Dropped widget from index ${fromIndex} to position ${toIndex} (distance: ${minDistance.toFixed(
|
||||||
2)})`)
|
// 2)})`)
|
||||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||||
} else {
|
} else {
|
||||||
Logger.log("NSectionEditor", `No valid drop target found for widget at index ${index}`)
|
Logger.warn("NSectionEditor", `No valid drop target found for widget at index ${index}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -264,17 +263,16 @@ NBox {
|
||||||
radius: Style.radiusS * scaling
|
radius: Style.radiusS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
onEntered: function (drag) {
|
onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered start drop zone")
|
||||||
Logger.log("NSectionEditor", "Entered start drop zone")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDropped: function (drop) {
|
onDropped: function (drop) {
|
||||||
Logger.log("NSectionEditor", "Dropped on start zone")
|
//Logger.log("NSectionEditor", "Dropped on start zone")
|
||||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||||
const fromIndex = drop.source.widgetIndex
|
const fromIndex = drop.source.widgetIndex
|
||||||
const toIndex = 0 // Insert at the beginning
|
const toIndex = 0 // Insert at the beginning
|
||||||
if (fromIndex !== toIndex) {
|
if (fromIndex !== toIndex) {
|
||||||
Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to beginning`)
|
//Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to beginning`)
|
||||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -299,17 +297,16 @@ NBox {
|
||||||
radius: Style.radiusS * scaling
|
radius: Style.radiusS * scaling
|
||||||
}
|
}
|
||||||
|
|
||||||
onEntered: function (drag) {
|
onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered end drop zone")
|
||||||
Logger.log("NSectionEditor", "Entered end drop zone")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDropped: function (drop) {
|
onDropped: function (drop) {
|
||||||
Logger.log("NSectionEditor", "Dropped on end zone")
|
//Logger.log("NSectionEditor", "Dropped on end zone")
|
||||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||||
const fromIndex = drop.source.widgetIndex
|
const fromIndex = drop.source.widgetIndex
|
||||||
const toIndex = widgetModel.length // Insert at the end
|
const toIndex = widgetModel.length // Insert at the end
|
||||||
if (fromIndex !== toIndex) {
|
if (fromIndex !== toIndex) {
|
||||||
Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to end`)
|
//Logger.log("NSectionEditor", `Dropped widget from index ${fromIndex} to end`)
|
||||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,9 @@ RowLayout {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
ColumnLayout {
|
NLabel {
|
||||||
spacing: Style.marginXXS * scaling
|
label: root.label
|
||||||
Layout.fillWidth: true
|
description: root.description
|
||||||
|
|
||||||
NText {
|
|
||||||
text: label
|
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
visible: label !== ""
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: description
|
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: description !== ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value
|
// Value
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ Item {
|
||||||
id: labelText
|
id: labelText
|
||||||
text: root.label
|
text: root.label
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurface
|
||||||
font.pointSize: Style.fontSize * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
@ -161,7 +161,7 @@ Item {
|
||||||
id: descriptionText
|
id: descriptionText
|
||||||
text: root.description
|
text: root.description
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurface
|
||||||
font.pointSize: Style.fontSize * scaling
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
|
|
@ -176,7 +176,7 @@ Item {
|
||||||
|
|
||||||
color: Color.mOnSurface
|
color: Color.mOnSurface
|
||||||
|
|
||||||
fontPointSize: Style.fontSize * scaling
|
fontPointSize: Style.fontSizeM * scaling
|
||||||
sizeRatio: 0.8
|
sizeRatio: 0.8
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,24 +19,9 @@ RowLayout {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
ColumnLayout {
|
NLabel {
|
||||||
spacing: Style.marginXXS * scaling
|
label: root.label
|
||||||
Layout.fillWidth: true
|
description: root.description
|
||||||
|
|
||||||
NText {
|
|
||||||
text: label
|
|
||||||
font.pointSize: Style.fontSizeM * scaling
|
|
||||||
font.weight: Style.fontWeightBold
|
|
||||||
color: Color.mOnSurface
|
|
||||||
}
|
|
||||||
|
|
||||||
NText {
|
|
||||||
text: description
|
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
|
||||||
color: Color.mOnSurfaceVariant
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue