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
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
NIconButton {
|
||||
icon: "refresh"
|
||||
|
|
@ -187,7 +187,6 @@ NPanel {
|
|||
colorBg: Color.mSurfaceVariant
|
||||
colorFg: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 35 * scaling
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
|
|
@ -201,7 +200,6 @@ NPanel {
|
|||
colorBg: ArchUpdaterService.updateInProgress ? Color.mSurfaceVariant : Color.mPrimary
|
||||
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : Color.mOnPrimary
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 35 * scaling
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
|
|
@ -219,7 +217,6 @@ NPanel {
|
|||
colorFg: ArchUpdaterService.updateInProgress ? Color.mOnSurfaceVariant : (ArchUpdaterService.selectedPackagesCount
|
||||
> 0 ? Color.mOnSecondary : Color.mOnSurfaceVariant)
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 35 * scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ NPanel {
|
|||
// Tab label on the main right side
|
||||
NText {
|
||||
text: root.tabsModel[currentTabIndex].label
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -287,21 +287,28 @@ NPanel {
|
|||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
|
||||
Repeater {
|
||||
model: root.tabsModel
|
||||
|
||||
onItemAdded: function (index, item) {
|
||||
item.sourceComponent = root.tabsModel[index].source
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
// All loaders will occupy the same space, stacked on top of each other.
|
||||
anchors.fill: parent
|
||||
visible: index === root.currentTabIndex
|
||||
// The loader is only active (and uses memory) when its page is visible.
|
||||
active: visible
|
||||
active: index === root.currentTabIndex
|
||||
sourceComponent: ColumnLayout {
|
||||
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 var contributors: GitHubService.contributors
|
||||
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Process {
|
||||
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 {
|
||||
text: "Noctalia: quiet by design"
|
||||
text: "Noctalia Shell"
|
||||
font.pointSize: Style.fontSizeXXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
|
|
@ -65,14 +47,6 @@ ColumnLayout {
|
|||
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 {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
columns: 2
|
||||
|
|
@ -163,8 +137,8 @@ ColumnLayout {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginxL * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
|
|
@ -258,5 +232,4 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,8 @@ import qs.Commons
|
|||
import qs.Services
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property real localVolume: AudioService.volume
|
||||
|
||||
// Connection used to open the pill when volume changes
|
||||
Connections {
|
||||
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
|
||||
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
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NLabel {
|
||||
label: "Master Volume"
|
||||
label: "Output Volume"
|
||||
description: "System-wide volume level."
|
||||
}
|
||||
|
||||
|
|
@ -141,24 +99,22 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// AudioService Devices
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
NText {
|
||||
text: "Audio Devices"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +145,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// Input Devices
|
||||
|
|
@ -223,25 +178,44 @@ ColumnLayout {
|
|||
// Divider
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// MPRIS Player Preferences
|
||||
// Media Player Preferences
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "MPRIS Player Preferences"
|
||||
text: "Media Player"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
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)
|
||||
NTextInput {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
label: "Preferred Player"
|
||||
description: "Substring to match MPRIS player (identity/bus/desktop)."
|
||||
placeholderText: "e.g. spotify, vlc, mpv"
|
||||
|
|
@ -266,7 +240,7 @@ ColumnLayout {
|
|||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
label: "Blacklist player"
|
||||
description: "Substring, e.g. plex, shim, mpv"
|
||||
description: "Substring, e.g. plex, shim, mpv."
|
||||
placeholderText: "type substring and press +"
|
||||
}
|
||||
|
||||
|
|
@ -355,46 +329,6 @@ ColumnLayout {
|
|||
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
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
|
|
@ -404,7 +338,7 @@ ColumnLayout {
|
|||
text: "Audio Visualizer"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
|
|
@ -439,7 +373,7 @@ ColumnLayout {
|
|||
|
||||
NComboBox {
|
||||
label: "Frame Rate"
|
||||
description: "Target frame rate for audio visualizer. (default: 60)"
|
||||
description: "Target frame rate for audio visualizer."
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 {
|
||||
Layout.fillWidth: true
|
||||
label: "Bar Position"
|
||||
description: "Choose where to place the bar on the screen."
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
key: "top"
|
||||
|
|
@ -65,9 +26,7 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
currentKey: Settings.data.bar.position
|
||||
onSelected: key => {
|
||||
Settings.data.bar.position = key
|
||||
}
|
||||
onSelected: key => Settings.data.bar.position = key
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,11 +109,12 @@ ColumnLayout {
|
|||
Settings.data.bar.showWorkspaceLabel = key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Widgets Management Section
|
||||
|
|
@ -190,7 +150,6 @@ ColumnLayout {
|
|||
sectionName: "Left"
|
||||
widgetModel: Settings.data.bar.widgets.left
|
||||
availableWidgets: availableWidgets
|
||||
scrollView: scrollView
|
||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||
|
|
@ -201,7 +160,6 @@ ColumnLayout {
|
|||
sectionName: "Center"
|
||||
widgetModel: Settings.data.bar.widgets.center
|
||||
availableWidgets: availableWidgets
|
||||
scrollView: scrollView
|
||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||
|
|
@ -212,15 +170,17 @@ ColumnLayout {
|
|||
sectionName: "Right"
|
||||
widgetModel: Settings.data.bar.widgets.right
|
||||
availableWidgets: availableWidgets
|
||||
scrollView: scrollView
|
||||
onAddWidget: (widgetName, section) => addWidgetToSection(widgetName, section)
|
||||
onRemoveWidget: (section, index) => removeWidgetFromSection(section, index)
|
||||
onReorderWidget: (section, fromIndex, toIndex) => reorderWidgetInSection(section, fromIndex, toIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
|
|
|||
|
|
@ -6,33 +6,11 @@ import qs.Commons
|
|||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
readonly property real scaling: ScalingService.scale(screen)
|
||||
readonly property string tabIcon: "brightness_6"
|
||||
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
|
||||
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
|
||||
ColumnLayout {
|
||||
|
|
@ -54,16 +32,9 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
}
|
||||
|
||||
// Monitor Overview Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
NLabel {
|
||||
label: "Monitors Brightness Control"
|
||||
|
|
@ -147,10 +118,9 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import qs.Widgets
|
|||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
spacing: 0
|
||||
|
||||
// Helper function to get color from scheme file (supports dark/light variants)
|
||||
function getSchemeColor(schemePath, colorKey) {
|
||||
// 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.
|
||||
Item {
|
||||
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 {
|
||||
width: scrollView.availableWidth
|
||||
spacing: 0
|
||||
|
|
@ -159,36 +168,30 @@ ColumnLayout {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Predefined Color Schemes"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
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."
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: Color.mOnSurface
|
||||
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.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
|
||||
// Color Schemes Grid
|
||||
GridLayout {
|
||||
columns: 4
|
||||
|
|
@ -340,28 +343,10 @@ 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 {}
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,11 @@ import qs.Commons
|
|||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
readonly property real scaling: ScalingService.scale(screen)
|
||||
readonly property string tabIcon: "monitor"
|
||||
readonly property string tabLabel: "Display"
|
||||
readonly property int tabIndex: 5
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
// Time dropdown options (00:00 .. 23:30)
|
||||
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 {
|
||||
text: "Per‑monitor configuration"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
text: "Monitor-specific configuration"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "By default, bars and notifications are shown on all displays. Select one or more below to narrow your view."
|
||||
font.pointSize: Style.fontSize * scaling
|
||||
text: "Bars and notifications appear on all displays by default. Choose specific displays below to limit where they're shown."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
|
||||
Repeater {
|
||||
model: Quickshell.screens || []
|
||||
delegate: Rectangle {
|
||||
|
|
@ -134,8 +120,8 @@ Item {
|
|||
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.notifications.monitors = addMonitor(
|
||||
Settings.data.notifications.monitors, modelData.name)
|
||||
Settings.data.notifications.monitors = addMonitor(Settings.data.notifications.monitors,
|
||||
modelData.name)
|
||||
} else {
|
||||
Settings.data.notifications.monitors = removeMonitor(
|
||||
Settings.data.notifications.monitors, modelData.name)
|
||||
|
|
@ -152,8 +138,7 @@ Item {
|
|||
if (checked) {
|
||||
Settings.data.dock.monitors = addMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors,
|
||||
modelData.name)
|
||||
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,67 +213,54 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Night Light Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
NText {
|
||||
text: "Night Light"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
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
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Enable Night Light"
|
||||
description: "Apply a warm color filter to reduce blue light emission."
|
||||
checked: Settings.data.nightLight.enabled
|
||||
onToggled: checked => {
|
||||
Settings.data.nightLight.enabled = checked
|
||||
}
|
||||
onToggled: checked => Settings.data.nightLight.enabled = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Auto Schedule"
|
||||
description: "Automatically enable night light based on time schedule."
|
||||
checked: Settings.data.nightLight.autoSchedule
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||
}
|
||||
|
||||
// Intensity settings
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
|
||||
NText {
|
||||
text: "Intensity"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
NLabel {
|
||||
label: "Intensity"
|
||||
description: "Higher values create warmer light."
|
||||
}
|
||||
|
||||
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 {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
|
||||
NSlider {
|
||||
from: 0
|
||||
|
|
@ -307,31 +279,24 @@ Item {
|
|||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule settings
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
|
||||
NText {
|
||||
text: "Schedule"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
NLabel {
|
||||
label: "Schedule"
|
||||
description: "Set a start and end time for automatic schedule."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
enabled: Settings.data.nightLight.enabled
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
Layout.fillWidth: false
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
NText {
|
||||
text: "Start Time"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
|
|
@ -340,33 +305,32 @@ Item {
|
|||
currentKey: Settings.data.nightLight.startTime
|
||||
placeholder: "Select start time"
|
||||
onSelected: key => Settings.data.nightLight.startTime = key
|
||||
}
|
||||
preferredWidth: 120 * scaling
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
Item {// add a little more spacing
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Stop Time"
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
model: timeOptions
|
||||
currentKey: Settings.data.nightLight.stopTime
|
||||
placeholder: "Select stop time"
|
||||
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
|
||||
|
||||
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
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL * scaling
|
||||
|
|
@ -71,8 +33,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -80,6 +40,7 @@ ColumnLayout {
|
|||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// User Interface
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -88,7 +49,7 @@ ColumnLayout {
|
|||
text: "User Interface"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
|
|
@ -123,19 +84,9 @@ ColumnLayout {
|
|||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Border radius"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
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
|
||||
NLabel {
|
||||
label: "Border radius"
|
||||
description: "Adjust the rounded border of all UI elements."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
|
@ -158,30 +109,14 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
}
|
||||
|
||||
// Animation Speed
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Animation Speed"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
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
|
||||
NLabel {
|
||||
label: "Animation Speed"
|
||||
description: "Adjust global animation speed."
|
||||
}
|
||||
|
||||
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 {
|
||||
text: "Fonts"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
// Font configuration section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
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
|
||||
|
||||
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: "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 {
|
||||
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.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 {
|
||||
text: "Launcher Background"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
text: "Adjust the background opacity of the launcher."
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
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.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 {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Interfaces"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NToggle {
|
||||
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
|
||||
|
||||
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: "Recordings"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
// Output Directory
|
||||
ColumnLayout {
|
||||
|
|
@ -55,6 +22,7 @@ ColumnLayout {
|
|||
onEditingFinished: {
|
||||
Settings.data.screenRecorder.directory = text
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -75,8 +43,8 @@ ColumnLayout {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Video Settings
|
||||
|
|
@ -88,7 +56,7 @@ ColumnLayout {
|
|||
text: "Video Settings"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +83,7 @@ ColumnLayout {
|
|||
// Frame Rate
|
||||
NComboBox {
|
||||
label: "Frame Rate"
|
||||
description: "Target frame rate for screen recordings. (default: 60)"
|
||||
description: "Target frame rate for screen recordings."
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
key: "30"
|
||||
|
|
@ -248,7 +216,7 @@ ColumnLayout {
|
|||
text: "Audio Settings"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
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
|
||||
|
||||
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
|
||||
ColumnLayout {
|
||||
spacing: Style.marginM * scaling
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
|
||||
NTextInput {
|
||||
label: "Location name"
|
||||
description: "Choose a known location near you."
|
||||
|
|
@ -58,12 +19,11 @@ ColumnLayout {
|
|||
LocationService.resetWeather()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Time section
|
||||
|
|
@ -75,8 +35,7 @@ ColumnLayout {
|
|||
text: "Time Format"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NToggle {
|
||||
|
|
@ -109,8 +68,8 @@ ColumnLayout {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Weather section
|
||||
|
|
@ -122,8 +81,7 @@ ColumnLayout {
|
|||
text: "Weather"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
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.Widgets
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
readonly property real scaling: ScalingService.scale(screen)
|
||||
readonly property string tabIcon: "photo_library"
|
||||
readonly property string tabLabel: "Wallpaper Selector"
|
||||
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
|
||||
Layout.margins: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
// Current wallpaper display
|
||||
NText {
|
||||
text: "Current Wallpaper"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
@ -54,10 +40,11 @@ Item {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Wallpaper selector
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
|
@ -69,12 +56,12 @@ Item {
|
|||
text: "Wallpaper Selector"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Click on a wallpaper to set it as your current wallpaper."
|
||||
color: Color.mOnSurface
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
@ -102,8 +89,7 @@ Item {
|
|||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: {
|
||||
return Math.ceil(
|
||||
WallpaperService.wallpaperList.length / wallpaperGridView.columns) * wallpaperGridView.cellHeight
|
||||
return Math.ceil(WallpaperService.wallpaperList.length / wallpaperGridView.columns) * wallpaperGridView.cellHeight
|
||||
}
|
||||
|
||||
GridView {
|
||||
|
|
@ -117,8 +103,7 @@ Item {
|
|||
interactive: false
|
||||
|
||||
property int columns: 5
|
||||
property int itemSize: Math.floor(
|
||||
(width - leftMargin - rightMargin - (4 * Style.marginS * scaling)) / columns)
|
||||
property int itemSize: Math.floor((width - leftMargin - rightMargin - (4 * Style.marginS * scaling)) / columns)
|
||||
|
||||
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
|
||||
cellHeight: Math.floor(itemSize * 0.67) + Style.marginS * scaling
|
||||
|
|
@ -151,19 +136,19 @@ Item {
|
|||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.transparent
|
||||
border.color: isSelected ? Color.mPrimary : Color.mSurface
|
||||
border.width: Math.max(1, Style.borderL * scaling)
|
||||
border.color: isSelected ? Color.mSecondary : Color.mSurface
|
||||
border.width: Math.max(1, Style.borderL * 1.5 * scaling)
|
||||
}
|
||||
|
||||
// Selection tick-mark
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Style.marginXS * scaling
|
||||
anchors.margins: Style.marginS * scaling
|
||||
width: 28 * scaling
|
||||
height: 28 * scaling
|
||||
radius: width / 2
|
||||
color: Color.mPrimary
|
||||
color: Color.mSecondary
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
visible: isSelected
|
||||
|
|
@ -172,7 +157,7 @@ Item {
|
|||
text: "check"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
color: Color.mOnSecondary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
|
@ -180,8 +165,8 @@ Item {
|
|||
// Hover effect
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mOnSurface
|
||||
opacity: mouseArea.containsMouse ? 0.1 : 0
|
||||
color: Color.mSurface
|
||||
opacity: (mouseArea.containsMouse || isSelected) ? 0 : 0.4
|
||||
radius: parent.radius
|
||||
|
||||
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
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
spacing: 0
|
||||
// Process to check if swww is installed
|
||||
Process {
|
||||
id: swwwCheck
|
||||
command: ["which", "swww"]
|
||||
running: false
|
||||
|
||||
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
|
||||
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!")
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Directory"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
label: "Wallpaper Directory"
|
||||
description: "Path to your wallpaper directory."
|
||||
|
|
@ -62,14 +39,11 @@ ColumnLayout {
|
|||
Settings.data.wallpaper.directory = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -80,8 +54,7 @@ ColumnLayout {
|
|||
text: "Automation"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
// Random Wallpaper
|
||||
|
|
@ -306,10 +279,11 @@ ColumnLayout {
|
|||
id: customRow
|
||||
visible: presetRow.customForcedVisible || !presetRow.isCurrentPreset
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
|
||||
NTextInput {
|
||||
label: "Custom Interval"
|
||||
description: "Enter time as HH:MM (e.g., 1:30)"
|
||||
description: "Enter time as HH:MM (e.g., 1:30)."
|
||||
text: {
|
||||
const s = Settings.data.wallpaper.randomInterval
|
||||
const h = Math.floor(s / 3600)
|
||||
|
|
@ -339,28 +313,27 @@ ColumnLayout {
|
|||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL * 2 * scaling
|
||||
Layout.bottomMargin: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// SWWW
|
||||
// Swww
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "SWWW"
|
||||
text: "Swww"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
// Use SWWW
|
||||
NToggle {
|
||||
label: "Use SWWW"
|
||||
description: "Use SWWW daemon for advanced wallpaper management."
|
||||
label: "Use Swww"
|
||||
description: "Use Swww daemon for advanced wallpaper management."
|
||||
checked: Settings.data.wallpaper.swww.enabled
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
|
|
@ -368,7 +341,7 @@ ColumnLayout {
|
|||
swwwCheck.running = true
|
||||
} else {
|
||||
Settings.data.wallpaper.swww.enabled = false
|
||||
ToastService.showNotice("SWWW", "Disabled")
|
||||
ToastService.showNotice("Swww", "Disabled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -383,7 +356,7 @@ ColumnLayout {
|
|||
// Resize Mode
|
||||
NComboBox {
|
||||
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 {
|
||||
ListElement {
|
||||
key: "no"
|
||||
|
|
@ -478,32 +451,14 @@ ColumnLayout {
|
|||
|
||||
// Transition FPS
|
||||
ColumnLayout {
|
||||
NLabel {
|
||||
label: "Transition FPS"
|
||||
description: "Frames per second for transition animations."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
spacing: Style.marginL * scaling
|
||||
NSlider {
|
||||
id: sliderWpTransitionFps
|
||||
Layout.fillWidth: true
|
||||
from: 30
|
||||
to: 500
|
||||
|
|
@ -512,36 +467,23 @@ ColumnLayout {
|
|||
onMoved: Settings.data.wallpaper.swww.transitionFps = Math.round(value)
|
||||
cutoutColor: Color.mSurface
|
||||
}
|
||||
NText {
|
||||
text: Settings.data.wallpaper.swww.transitionFps + " FPS"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition Duration
|
||||
ColumnLayout {
|
||||
NLabel {
|
||||
label: "Transition Duration"
|
||||
description: "Duration of transition animations in seconds."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
spacing: Style.marginL * scaling
|
||||
NSlider {
|
||||
id: sliderWpTransitionDuration
|
||||
Layout.fillWidth: true
|
||||
from: 0.25
|
||||
to: 10
|
||||
|
|
@ -550,31 +492,18 @@ ColumnLayout {
|
|||
onMoved: Settings.data.wallpaper.swww.transitionDuration = value
|
||||
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
|
||||
Process {
|
||||
id: swwwCheck
|
||||
command: ["which", "swww"]
|
||||
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 {}
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import qs.Commons
|
|||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
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 description: ""
|
||||
|
|
@ -23,11 +24,6 @@ ColumnLayout {
|
|||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
}
|
||||
|
||||
function findIndexByKey(key) {
|
||||
for (var i = 0; i < root.model.count; i++) {
|
||||
if (root.model.get(i).key === key) {
|
||||
|
|
@ -37,10 +33,15 @@ ColumnLayout {
|
|||
return -1
|
||||
}
|
||||
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: combo
|
||||
|
||||
Layout.preferredWidth: 320 * scaling
|
||||
Layout.preferredWidth: root.preferredWidth
|
||||
Layout.preferredHeight: height
|
||||
model: model
|
||||
currentIndex: findIndexByKey(currentKey)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ ColumnLayout {
|
|||
|
||||
NText {
|
||||
text: label
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
visible: label !== ""
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ NBox {
|
|||
property string sectionName: ""
|
||||
property var widgetModel: []
|
||||
property var availableWidgets: []
|
||||
property var scrollView: null
|
||||
|
||||
signal addWidget(string widgetName, string section)
|
||||
signal removeWidget(string section, int index)
|
||||
|
|
@ -23,7 +22,7 @@ NBox {
|
|||
if (widgetCount === 0)
|
||||
return 140 * scaling
|
||||
|
||||
var availableWidth = scrollView ? scrollView.availableWidth - (Style.marginM * scaling * 2) : 400 * scaling
|
||||
var availableWidth = parent.width
|
||||
var avgWidgetWidth = 150 * scaling
|
||||
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
|
||||
var rows = Math.ceil(widgetCount / widgetsPerRow)
|
||||
|
|
@ -52,7 +51,7 @@ NBox {
|
|||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * scaling
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
RowLayout {
|
||||
|
|
@ -189,13 +188,13 @@ NBox {
|
|||
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
|
||||
widgetItem.z = 1000
|
||||
}
|
||||
|
||||
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
|
||||
widgetItem.z = 0
|
||||
|
||||
|
|
@ -232,13 +231,13 @@ NBox {
|
|||
if (targetIndex !== -1 && targetIndex !== index) {
|
||||
const fromIndex = index
|
||||
const toIndex = targetIndex
|
||||
Logger.log(
|
||||
"NSectionEditor",
|
||||
`Dropped widget from index ${fromIndex} to position ${toIndex} (distance: ${minDistance.toFixed(
|
||||
2)})`)
|
||||
// Logger.log(
|
||||
// "NSectionEditor",
|
||||
// `Dropped widget from index ${fromIndex} to position ${toIndex} (distance: ${minDistance.toFixed(
|
||||
// 2)})`)
|
||||
reorderWidget(sectionName.toLowerCase(), fromIndex, toIndex)
|
||||
} 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
|
||||
}
|
||||
|
||||
onEntered: function (drag) {
|
||||
Logger.log("NSectionEditor", "Entered start drop zone")
|
||||
onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered start drop zone")
|
||||
}
|
||||
|
||||
onDropped: function (drop) {
|
||||
Logger.log("NSectionEditor", "Dropped on start zone")
|
||||
//Logger.log("NSectionEditor", "Dropped on start zone")
|
||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||
const fromIndex = drop.source.widgetIndex
|
||||
const toIndex = 0 // Insert at the beginning
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -299,17 +297,16 @@ NBox {
|
|||
radius: Style.radiusS * scaling
|
||||
}
|
||||
|
||||
onEntered: function (drag) {
|
||||
Logger.log("NSectionEditor", "Entered end drop zone")
|
||||
onEntered: function (drag) {//Logger.log("NSectionEditor", "Entered end drop zone")
|
||||
}
|
||||
|
||||
onDropped: function (drop) {
|
||||
Logger.log("NSectionEditor", "Dropped on end zone")
|
||||
//Logger.log("NSectionEditor", "Dropped on end zone")
|
||||
if (drop.source && drop.source.widgetIndex !== undefined) {
|
||||
const fromIndex = drop.source.widgetIndex
|
||||
const toIndex = widgetModel.length // Insert at the end
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,26 +30,9 @@ RowLayout {
|
|||
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
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 !== ""
|
||||
}
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
}
|
||||
|
||||
// Value
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ Item {
|
|||
id: labelText
|
||||
text: root.label
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSize * scaling
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
|
|
@ -161,7 +161,7 @@ Item {
|
|||
id: descriptionText
|
||||
text: root.description
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSize * scaling
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
visible: text.length > 0
|
||||
|
|
@ -176,7 +176,7 @@ Item {
|
|||
|
||||
color: Color.mOnSurface
|
||||
|
||||
fontPointSize: Style.fontSize * scaling
|
||||
fontPointSize: Style.fontSizeM * scaling
|
||||
sizeRatio: 0.8
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
|
|
|
|||
|
|
@ -19,24 +19,9 @@ RowLayout {
|
|||
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
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
|
||||
}
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue