Files
noctalia-shell/Modules/Settings/Tabs/GeneralTab.qml
T

366 lines
11 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services
import qs.Widgets
ColumnLayout {
id: root
NHeader {
label: I18n.tr("settings.general.profile.section.label")
description: I18n.tr("settings.general.profile.section.description")
}
// Profile section
RowLayout {
Layout.fillWidth: true
spacing: Style.marginL * scaling
// Avatar preview
NImageCircled {
width: 108 * scaling
height: 108 * scaling
imagePath: Settings.data.general.avatarImage
fallbackIcon: "person"
borderColor: Color.mPrimary
borderWidth: Math.max(1, Style.borderM * scaling)
Layout.alignment: Qt.AlignTop
}
NTextInputButton {
label: I18n.tr("settings.general.profile.picture.label", {
"user": Quickshell.env("USER" || "User")
})
description: I18n.tr("settings.general.profile.picture.description")
text: Settings.data.general.avatarImage
placeholderText: I18n.tr("placeholders.profile-picture-path")
buttonIcon: "photo"
buttonTooltip: "Browse for avatar image"
onInputEditingFinished: Settings.data.general.avatarImage = text
onButtonClicked: {
avatarPicker.openFilePicker()
}
}
}
NFilePicker {
id: avatarPicker
title: I18n.tr("settings.general.profile.select-avatar")
selectionMode: "files"
initialPath: Settings.data.general.avatarImage.substr(0, Settings.data.general.avatarImage.lastIndexOf("/")) || Quickshell.env("HOME")
nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"]
onAccepted: paths => {
if (paths.length > 0) {
Settings.data.general.avatarImage = paths[0]
}
}
}
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL * scaling
Layout.bottomMargin: Style.marginXL * scaling
}
// User Interface
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.general.ui.section.label")
description: I18n.tr("settings.general.ui.section.description")
}
NToggle {
label: I18n.tr("settings.general.ui.dim-desktop.label")
description: I18n.tr("settings.general.ui.dim-desktop.description")
checked: Settings.data.general.dimDesktop
onToggled: checked => Settings.data.general.dimDesktop = checked
}
ColumnLayout {
spacing: Style.marginXXS * scaling
Layout.fillWidth: true
NLabel {
label: I18n.tr("settings.general.ui.border-radius.label")
description: I18n.tr("settings.general.ui.border-radius.description")
}
NValueSlider {
Layout.fillWidth: true
from: 0
to: 1
stepSize: 0.01
value: Settings.data.general.radiusRatio
onMoved: value => Settings.data.general.radiusRatio = value
text: Math.floor(Settings.data.general.radiusRatio * 100) + "%"
}
}
// Animation Speed
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NToggle {
label: I18n.tr("settings.general.ui.animation-disable.label")
description: I18n.tr("settings.general.ui.animation-disable.description")
checked: Settings.data.general.animationDisabled
onToggled: checked => Settings.data.general.animationDisabled = checked
}
ColumnLayout {
spacing: Style.marginXXS * scaling
Layout.fillWidth: true
visible: !Settings.data.general.animationDisabled
NLabel {
label: I18n.tr("settings.general.ui.animation-speed.label")
description: I18n.tr("settings.general.ui.animation-speed.description")
}
NValueSlider {
Layout.fillWidth: true
from: 0.1
to: 2.0
stepSize: 0.01
value: Settings.data.general.animationSpeed
onMoved: value => Settings.data.general.animationSpeed = value
text: Math.round(Settings.data.general.animationSpeed * 100) + "%"
}
}
}
}
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL * scaling
Layout.bottomMargin: Style.marginXL * scaling
}
// Dock
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.general.screen-corners.section.label")
description: I18n.tr("settings.general.screen-corners.section.description")
}
NToggle {
label: I18n.tr("settings.general.screen-corners.show-corners.label")
description: I18n.tr("settings.general.screen-corners.show-corners.description")
checked: Settings.data.general.showScreenCorners
onToggled: checked => Settings.data.general.showScreenCorners = checked
}
NToggle {
label: I18n.tr("settings.general.screen-corners.solid-black.label")
description: I18n.tr("settings.general.screen-corners.solid-black.description")
checked: Settings.data.general.forceBlackScreenCorners
onToggled: checked => Settings.data.general.forceBlackScreenCorners = checked
}
ColumnLayout {
spacing: Style.marginXXS * scaling
Layout.fillWidth: true
NLabel {
label: I18n.tr("settings.general.screen-corners.radius.label")
description: I18n.tr("settings.general.screen-corners.radius.description")
}
NValueSlider {
Layout.fillWidth: true
from: 0
to: 2
stepSize: 0.01
value: Settings.data.general.screenRadiusRatio
onMoved: value => Settings.data.general.screenRadiusRatio = value
text: Math.floor(Settings.data.general.screenRadiusRatio * 100) + "%"
}
}
}
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL * scaling
Layout.bottomMargin: Style.marginXL * scaling
}
// Control Center
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.general.control-center.section.label")
description: I18n.tr("settings.general.control-center.section.description")
}
NComboBox {
id: controlCenterPosition
label: I18n.tr("settings.general.control-center.position.label")
description: I18n.tr("settings.general.control-center.position.description")
Layout.fillWidth: true
model: [{
"key": "close_to_bar_button",
"name": I18n.tr("options.control-center.position.close_to_bar_button")
}, {
"key": "top_left",
"name": I18n.tr("options.control-center.position.top_left")
}, {
"key": "top_right",
"name": I18n.tr("options.control-center.position.top_right")
}, {
"key": "bottom_left",
"name": I18n.tr("options.control-center.position.bottom_left")
}, {
"key": "bottom_right",
"name": I18n.tr("options.control-center.position.bottom_right")
}, {
"key": "bottom_center",
"name": I18n.tr("options.control-center.position.bottom_center")
}, {
"key": "top_center",
"name": I18n.tr("options.control-center.position.top_center")
}]
currentKey: Settings.data.controlCenter.position
onSelected: function (key) {
Settings.data.controlCenter.position = key
}
}
}
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL * scaling
Layout.bottomMargin: Style.marginXL * scaling
}
// Fonts
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NHeader {
label: I18n.tr("settings.general.fonts.section.label")
description: I18n.tr("settings.general.fonts.section.description")
}
// Font configuration section
ColumnLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NSearchableComboBox {
label: I18n.tr("settings.general.fonts.default.label")
description: I18n.tr("settings.general.fonts.default.description")
model: FontService.availableFonts
currentKey: Settings.data.ui.fontDefault
placeholder: I18n.tr("settings.general.fonts.default.placeholder")
searchPlaceholder: I18n.tr("settings.general.fonts.default.search-placeholder")
popupHeight: 420 * scaling
minimumWidth: 300 * scaling
onSelected: function (key) {
Settings.data.ui.fontDefault = key
}
}
NSearchableComboBox {
label: I18n.tr("settings.general.fonts.monospace.label")
description: I18n.tr("settings.general.fonts.monospace.description")
model: FontService.monospaceFonts
currentKey: Settings.data.ui.fontFixed
placeholder: I18n.tr("settings.general.fonts.monospace.placeholder")
searchPlaceholder: I18n.tr("settings.general.fonts.monospace.search-placeholder")
popupHeight: 320 * scaling
minimumWidth: 300 * scaling
onSelected: function (key) {
Settings.data.ui.fontFixed = key
}
}
ColumnLayout {
NLabel {
label: I18n.tr("settings.general.fonts.default.scale.label")
description: I18n.tr("settings.general.fonts.default.scale.description")
}
RowLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NValueSlider {
Layout.fillWidth: true
from: 0.75
to: 1.25
stepSize: 0.01
value: Settings.data.ui.fontDefaultScale
onMoved: value => Settings.data.ui.fontDefaultScale = value
text: Math.floor(Settings.data.ui.fontDefaultScale * 100) + "%"
}
// Reset button container
Item {
Layout.preferredWidth: 30 * scaling
Layout.preferredHeight: 30 * scaling
NIconButton {
icon: "refresh"
baseSize: Style.baseWidgetSize * 0.9
tooltipText: I18n.tr("settings.general.fonts.reset-scaling")
onClicked: Settings.data.ui.fontDefaultScale = 1.0
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
ColumnLayout {
NLabel {
label: I18n.tr("settings.general.fonts.monospace.scale.label")
description: I18n.tr("settings.general.fonts.monospace.scale.description")
}
RowLayout {
spacing: Style.marginL * scaling
Layout.fillWidth: true
NValueSlider {
Layout.fillWidth: true
from: 0.75
to: 1.25
stepSize: 0.01
value: Settings.data.ui.fontFixedScale
onMoved: value => Settings.data.ui.fontFixedScale = value
text: Math.floor(Settings.data.ui.fontFixedScale * 100) + "%"
}
// Reset button container
Item {
Layout.preferredWidth: 30 * scaling
Layout.preferredHeight: 30 * scaling
NIconButton {
icon: "refresh"
baseSize: Style.baseWidgetSize * 0.9
tooltipText: I18n.tr("settings.general.fonts.reset-scaling")
onClicked: Settings.data.ui.fontFixedScale = 1.0
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
}
}