mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
SettingsContent: add collapsible button for tab area
This commit is contained in:
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Bildschirmrekorder (Aufnahme starten)",
|
||||
"click-to-stop-recording": "Bildschirmrekorder (Aufnahme stoppen)",
|
||||
"close": "Schließen",
|
||||
"collapse": "Seitenleiste einklappen",
|
||||
"connect-disconnect-devices": "Bluetooth-Gerät",
|
||||
"delete-notification": "Benachrichtigung löschen",
|
||||
"disable-keep-awake": "Wach halten",
|
||||
"do-not-disturb-disabled": "Nicht stören",
|
||||
"do-not-disturb-enabled": "Nicht stören",
|
||||
"enable-keep-awake": "Wach halten",
|
||||
"expand": "Seitenleiste ausklappen",
|
||||
"forget-network": "Netzwerk vergessen",
|
||||
"grid-view": "Rasteransicht",
|
||||
"hidden-files-hide": "Versteckte Dateien",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Screen recorder (start recording)",
|
||||
"click-to-stop-recording": "Screen recorder (stop recording)",
|
||||
"close": "Close",
|
||||
"collapse": "Collapse sidebar",
|
||||
"connect-disconnect-devices": "Bluetooth device",
|
||||
"delete-notification": "Delete notification",
|
||||
"disable-keep-awake": "Keep Awake",
|
||||
"do-not-disturb-disabled": "Do Not Disturb",
|
||||
"do-not-disturb-enabled": "Do Not Disturb",
|
||||
"enable-keep-awake": "Keep Awake",
|
||||
"expand": "Expand sidebar",
|
||||
"forget-network": "Forget network",
|
||||
"grid-view": "Grid view",
|
||||
"hidden-files-hide": "Hidden files",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Grabadora de pantalla (iniciar grabación)",
|
||||
"click-to-stop-recording": "Grabadora de pantalla (detener grabación)",
|
||||
"close": "Cerrar",
|
||||
"collapse": "Colapsar barra lateral",
|
||||
"connect-disconnect-devices": "Dispositivo Bluetooth",
|
||||
"delete-notification": "Eliminar notificación",
|
||||
"disable-keep-awake": "Mantener despierto",
|
||||
"do-not-disturb-disabled": "No molestar",
|
||||
"do-not-disturb-enabled": "No molestar",
|
||||
"enable-keep-awake": "Mantener despierto",
|
||||
"expand": "Expandir barra lateral",
|
||||
"forget-network": "Olvidar red",
|
||||
"grid-view": "Vista de cuadrícula",
|
||||
"hidden-files-hide": "Archivos ocultos",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Enregistreur d'écran (démarrer l'enregistrement)",
|
||||
"click-to-stop-recording": "Enregistreur d'écran (arrêter l'enregistrement)",
|
||||
"close": "Fermer",
|
||||
"collapse": "Réduire la barre latérale",
|
||||
"connect-disconnect-devices": "Appareil Bluetooth",
|
||||
"delete-notification": "Supprimer la notification",
|
||||
"disable-keep-awake": "Rester éveillé",
|
||||
"do-not-disturb-disabled": "Ne pas déranger",
|
||||
"do-not-disturb-enabled": "Ne pas déranger",
|
||||
"enable-keep-awake": "Rester éveillé",
|
||||
"expand": "Développer la barre latérale",
|
||||
"forget-network": "Oublier le réseau",
|
||||
"grid-view": "Vue en grille",
|
||||
"hidden-files-hide": "Fichiers cachés",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "画面録画 (録画開始)",
|
||||
"click-to-stop-recording": "画面録画 (録画停止)",
|
||||
"close": "閉じる",
|
||||
"collapse": "サイドバーを折りたたむ",
|
||||
"connect-disconnect-devices": "Bluetooth デバイス",
|
||||
"delete-notification": "通知を削除",
|
||||
"disable-keep-awake": "スリープ防止",
|
||||
"do-not-disturb-disabled": "おやすみモード",
|
||||
"do-not-disturb-enabled": "おやすみモード",
|
||||
"enable-keep-awake": "スリープ防止",
|
||||
"expand": "サイドバーを展開",
|
||||
"forget-network": "ネットワーク設定を削除",
|
||||
"grid-view": "グリッド表示",
|
||||
"hidden-files-hide": "隠しファイル",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Schermrecorder (opname starten)",
|
||||
"click-to-stop-recording": "Schermrecorder (opname stoppen)",
|
||||
"close": "Sluiten",
|
||||
"collapse": "Zijbalk inklappen",
|
||||
"connect-disconnect-devices": "Bluetooth-apparaat",
|
||||
"delete-notification": "Melding verwijderen",
|
||||
"disable-keep-awake": "Wakker houden",
|
||||
"do-not-disturb-disabled": "Niet storen",
|
||||
"do-not-disturb-enabled": "Niet storen",
|
||||
"enable-keep-awake": "Wakker houden",
|
||||
"expand": "Zijbalk uitklappen",
|
||||
"forget-network": "Netwerk vergeten",
|
||||
"grid-view": "Rasterweergave",
|
||||
"hidden-files-hide": "Verborgen bestanden",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Gravador de tela (iniciar gravação)",
|
||||
"click-to-stop-recording": "Gravador de tela (parar gravação)",
|
||||
"close": "Fechar",
|
||||
"collapse": "Recolher barra lateral",
|
||||
"connect-disconnect-devices": "Dispositivo Bluetooth",
|
||||
"delete-notification": "Excluir notificação",
|
||||
"disable-keep-awake": "Manter acordado",
|
||||
"do-not-disturb-disabled": "Não perturbe",
|
||||
"do-not-disturb-enabled": "Não perturbe",
|
||||
"enable-keep-awake": "Manter acordado",
|
||||
"expand": "Expandir barra lateral",
|
||||
"forget-network": "Esquecer rede",
|
||||
"grid-view": "Visualização em grade",
|
||||
"hidden-files-hide": "Arquivos ocultos",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Запись экрана (начать запись)",
|
||||
"click-to-stop-recording": "Запись экрана (остановить запись)",
|
||||
"close": "Закрыть",
|
||||
"collapse": "Свернуть боковую панель",
|
||||
"connect-disconnect-devices": "Устройство Bluetooth",
|
||||
"delete-notification": "Удалить уведомление",
|
||||
"disable-keep-awake": "Не засыпать",
|
||||
"do-not-disturb-disabled": "Не беспокоить",
|
||||
"do-not-disturb-enabled": "Не беспокоить",
|
||||
"enable-keep-awake": "Не засыпать",
|
||||
"expand": "Развернуть боковую панель",
|
||||
"forget-network": "Забыть сеть",
|
||||
"grid-view": "Вид сеткой",
|
||||
"hidden-files-hide": "Скрытые файлы",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Ekran kaydedici (kaydı başlat)",
|
||||
"click-to-stop-recording": "Ekran kaydedici (kaydı durdur)",
|
||||
"close": "Kapat",
|
||||
"collapse": "Kenar çubuğunu daralt",
|
||||
"connect-disconnect-devices": "Bluetooth cihazı",
|
||||
"delete-notification": "Bildiriyi sil",
|
||||
"disable-keep-awake": "Uyanık kal",
|
||||
"do-not-disturb-disabled": "Rahatsız etme",
|
||||
"do-not-disturb-enabled": "Rahatsız etme",
|
||||
"enable-keep-awake": "Uyanık kal",
|
||||
"expand": "Kenar çubuğunu genişlet",
|
||||
"forget-network": "Ağı unut",
|
||||
"grid-view": "Izgara görünümü",
|
||||
"hidden-files-hide": "Gizli dosyalar",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "Запис екрана (почати запис)",
|
||||
"click-to-stop-recording": "Запис екрана (зупинити запис)",
|
||||
"close": "Закрити",
|
||||
"collapse": "Згорнути бічну панель",
|
||||
"connect-disconnect-devices": "Пристрій Bluetooth",
|
||||
"delete-notification": "Видалити сповіщення",
|
||||
"disable-keep-awake": "Заборона сну",
|
||||
"do-not-disturb-disabled": "Не турбувати",
|
||||
"do-not-disturb-enabled": "Не турбувати",
|
||||
"enable-keep-awake": "Заборона сну",
|
||||
"expand": "Розгорнути бічну панель",
|
||||
"forget-network": "Забути мережу",
|
||||
"grid-view": "Мережевий вигляд",
|
||||
"hidden-files-hide": "Приховані файли",
|
||||
|
||||
@@ -2453,12 +2453,14 @@
|
||||
"click-to-start-recording": "屏幕录制器(开始录制)",
|
||||
"click-to-stop-recording": "屏幕录制器(停止录制)",
|
||||
"close": "关闭",
|
||||
"collapse": "折叠侧边栏",
|
||||
"connect-disconnect-devices": "蓝牙设备",
|
||||
"delete-notification": "删除通知",
|
||||
"disable-keep-awake": "保持唤醒",
|
||||
"do-not-disturb-disabled": "勿扰模式",
|
||||
"do-not-disturb-enabled": "勿扰模式",
|
||||
"enable-keep-awake": "保持唤醒",
|
||||
"expand": "展开侧边栏",
|
||||
"forget-network": "忘记网络",
|
||||
"grid-view": "网格视图",
|
||||
"hidden-files-hide": "隐藏文件",
|
||||
|
||||
+29
-1
@@ -61,6 +61,11 @@ Singleton {
|
||||
schemes: [],
|
||||
timestamp: 0
|
||||
})
|
||||
|
||||
// UI state: settings panel, etc.
|
||||
property var ui: ({
|
||||
settingsSidebarExpanded: true
|
||||
})
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
@@ -171,6 +176,28 @@ Singleton {
|
||||
};
|
||||
}
|
||||
|
||||
// UI state
|
||||
function setUiState(stateData) {
|
||||
adapter.ui = stateData;
|
||||
save();
|
||||
}
|
||||
|
||||
function getUiState() {
|
||||
return adapter.ui || {
|
||||
settingsSidebarExpanded: true
|
||||
};
|
||||
}
|
||||
|
||||
function setSettingsSidebarExpanded(expanded) {
|
||||
let uiState = getUiState();
|
||||
uiState.settingsSidebarExpanded = expanded;
|
||||
setUiState(uiState);
|
||||
}
|
||||
|
||||
function getSettingsSidebarExpanded() {
|
||||
return getUiState().settingsSidebarExpanded !== false; // default to true
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
function buildStateSnapshot() {
|
||||
try {
|
||||
@@ -189,7 +216,8 @@ Singleton {
|
||||
display: shellStateData.display || {},
|
||||
notificationsState: shellStateData.notificationsState || {},
|
||||
changelogState: shellStateData.changelogState || {},
|
||||
colorSchemesList: shellStateData.colorSchemesList || {}
|
||||
colorSchemesList: shellStateData.colorSchemesList || {},
|
||||
ui: shellStateData.ui || {}
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import qs.Modules.Panels.Settings.Tabs
|
||||
import qs.Modules.Panels.Settings.Tabs.ColorScheme
|
||||
import qs.Modules.Panels.Settings.Tabs.SessionMenu
|
||||
import qs.Services.System
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
@@ -19,12 +20,20 @@ Item {
|
||||
property int currentTabIndex: 0
|
||||
property var tabsModel: []
|
||||
property var activeScrollView: null
|
||||
property bool sidebarExpanded: true
|
||||
|
||||
// Signal when close button is clicked
|
||||
signal closeRequested
|
||||
|
||||
// Save sidebar state when it changes
|
||||
onSidebarExpandedChanged: {
|
||||
ShellState.setSettingsSidebarExpanded(sidebarExpanded);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateTabsModel();
|
||||
// Restore sidebar state
|
||||
sidebarExpanded = ShellState.getSettingsSidebarExpanded();
|
||||
}
|
||||
|
||||
// Tab components
|
||||
@@ -323,120 +332,193 @@ Item {
|
||||
Rectangle {
|
||||
id: sidebar
|
||||
clip: true
|
||||
Layout.preferredWidth: 200 * Style.uiScaleRatio
|
||||
Layout.preferredWidth: root.sidebarExpanded ? 200 * Style.uiScaleRatio : sidebarToggle.width
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
color: Color.transparent
|
||||
|
||||
Item {
|
||||
Behavior on Layout.preferredWidth {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
NListView {
|
||||
id: sidebarList
|
||||
anchors.fill: parent
|
||||
model: root.tabsModel
|
||||
spacing: Style.marginXS
|
||||
currentIndex: root.currentTabIndex
|
||||
verticalPolicy: ScrollBar.AsNeeded
|
||||
// Sidebar toggle button
|
||||
Item {
|
||||
id: toggleContainer
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: toggleRow.implicitHeight + Style.marginS * 2
|
||||
|
||||
delegate: Rectangle {
|
||||
id: tabItem
|
||||
width: sidebarList.verticalScrollBarActive ? sidebarList.width - sidebarList.scrollBarWidth - Style.marginXS : sidebarList.width
|
||||
height: tabEntryRow.implicitHeight + Style.marginS * 2
|
||||
Rectangle {
|
||||
id: sidebarToggle
|
||||
width: toggleRow.implicitWidth + Style.marginS * 2
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
radius: Style.radiusS
|
||||
color: selected ? Color.mPrimary : (tabItem.hovering ? Color.mHover : Color.transparent)
|
||||
readonly property bool selected: index === root.currentTabIndex
|
||||
property bool hovering: false
|
||||
property color tabTextColor: selected ? Color.mOnPrimary : (tabItem.hovering ? Color.mOnHover : Color.mOnSurface)
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
color: toggleMouseArea.containsMouse ? Color.mHover : Color.transparent
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on tabTextColor {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: tabEntryRow
|
||||
anchors.fill: parent
|
||||
id: toggleRow
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.rightMargin: Style.marginS
|
||||
spacing: Style.marginM
|
||||
spacing: 0
|
||||
|
||||
NIcon {
|
||||
icon: modelData.icon
|
||||
color: tabTextColor
|
||||
icon: root.sidebarExpanded ? "layout-sidebar-left-expand" : "layout-sidebar-right-expand"
|
||||
color: Color.mOnSurface
|
||||
pointSize: Style.fontSizeXL
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr(modelData.label)
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightSemiBold
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: toggleMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: tabItem.hovering = true
|
||||
onExited: tabItem.hovering = false
|
||||
onCanceled: tabItem.hovering = false
|
||||
onClicked: root.currentTabIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== root.currentTabIndex) {
|
||||
root.currentTabIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentTabIndexChanged() {
|
||||
if (sidebarList.currentIndex !== root.currentTabIndex) {
|
||||
sidebarList.currentIndex = root.currentTabIndex;
|
||||
sidebarList.positionViewAtIndex(root.currentTabIndex, ListView.Contain);
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onEntered: {
|
||||
TooltipService.show(sidebarToggle, root.sidebarExpanded ? I18n.tr("tooltips.collapse") : I18n.tr("tooltips.expand"));
|
||||
}
|
||||
onExited: {
|
||||
TooltipService.hide();
|
||||
}
|
||||
onClicked: {
|
||||
TooltipService.hide();
|
||||
root.sidebarExpanded = !root.sidebarExpanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay gradient for sidebar scrolling
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.borderS
|
||||
radius: Style.radiusM
|
||||
color: Color.transparent
|
||||
visible: sidebarList.verticalScrollBarActive
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Color.transparent
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
NListView {
|
||||
id: sidebarList
|
||||
anchors.fill: parent
|
||||
model: root.tabsModel
|
||||
spacing: Style.marginXS
|
||||
currentIndex: root.currentTabIndex
|
||||
verticalPolicy: ScrollBar.AsNeeded
|
||||
|
||||
delegate: Rectangle {
|
||||
id: tabItem
|
||||
width: sidebarList.verticalScrollBarActive ? sidebarList.width - sidebarList.scrollBarWidth - Style.marginXS : sidebarList.width
|
||||
height: tabEntryRow.implicitHeight + Style.marginS * 2
|
||||
radius: Style.radiusS
|
||||
color: selected ? Color.mPrimary : (tabItem.hovering ? Color.mHover : Color.transparent)
|
||||
readonly property bool selected: index === root.currentTabIndex
|
||||
property bool hovering: false
|
||||
property color tabTextColor: selected ? Color.mOnPrimary : (tabItem.hovering ? Color.mOnHover : Color.mOnSurface)
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on tabTextColor {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: tabEntryRow
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.rightMargin: Style.marginS
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: modelData.icon
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeXL
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr(modelData.label)
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightSemiBold
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: root.sidebarExpanded
|
||||
opacity: root.sidebarExpanded ? 1.0 : 0.0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: tabItem.hovering = true
|
||||
onExited: tabItem.hovering = false
|
||||
onCanceled: tabItem.hovering = false
|
||||
onClicked: root.currentTabIndex = index
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.95
|
||||
color: Color.transparent
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== root.currentTabIndex) {
|
||||
root.currentTabIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Color.mSurfaceVariant
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentTabIndexChanged() {
|
||||
if (sidebarList.currentIndex !== root.currentTabIndex) {
|
||||
sidebarList.currentIndex = root.currentTabIndex;
|
||||
sidebarList.positionViewAtIndex(root.currentTabIndex, ListView.Contain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay gradient for sidebar scrolling
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.borderS
|
||||
radius: Style.radiusM
|
||||
color: Color.transparent
|
||||
visible: sidebarList.verticalScrollBarActive
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.95
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Color.mSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user