From the 2026-06-15 hardware-test feedback (redesign passed end-to-end):
- Glyphs: map the 12 unmapped additions-page icon names (brush, cloud_sync,
data_object, deployed_code, movie_edit, neurology, psychology, robot_2,
smart_toy, sports_esports, videocam, vpn_lock) so the nexus Additional
Software page stops rendering "?" boxes. Verified Nerd Font codepoints.
- Glyphs: cp() now uses String.fromCodePoint, not fromCharCode — the 5 MDI
glyphs above 0xFFFF were being truncated by the 16-bit fromCharCode.
- Shortcuts: Super+Escape (session) now drives the redesigned full-screen
Power Menu via NsShell.toggle("power"); old caelestia session panel is
now dead code.
- nexus LanguageAndRegion: replace the "coming soon" weather placeholder with
a real location input bound to GlobalConfig.services.weatherLocation (the
Weather backend already geocodes / IP-auto-detects).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
205 lines
6.8 KiB
QML
205 lines
6.8 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import Caelestia.Config
|
|
import qs.components
|
|
import qs.components.controls
|
|
import qs.services
|
|
import qs.modules.nexus.common
|
|
|
|
PageBase {
|
|
id: root
|
|
|
|
// Temperature units (index 0 = Celsius, 1 = Fahrenheit — matches Weather.formatTemp)
|
|
readonly property list<MenuItem> tempItems: [
|
|
MenuItem {
|
|
text: "°C"
|
|
},
|
|
MenuItem {
|
|
text: "°F"
|
|
}
|
|
]
|
|
|
|
// Clock format (index 0 = 24-hour, 1 = 12-hour — matches Time.useTwelveHourClock)
|
|
readonly property list<MenuItem> clockItems: [
|
|
MenuItem {
|
|
text: qsTr("24-hour")
|
|
},
|
|
MenuItem {
|
|
text: qsTr("12-hour")
|
|
}
|
|
]
|
|
|
|
title: qsTr("Language & region")
|
|
|
|
ColumnLayout {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.top: parent.top
|
|
width: root.cappedWidth
|
|
spacing: Tokens.spacing.extraSmall / 2
|
|
|
|
// Language
|
|
SectionHeader {
|
|
first: true
|
|
text: qsTr("Language")
|
|
}
|
|
|
|
// Read-only: the shell follows the system locale (no in-shell translations yet)
|
|
ConnectedRect {
|
|
Layout.fillWidth: true
|
|
first: true
|
|
last: true
|
|
implicitHeight: localeLayout.implicitHeight + localeLayout.anchors.margins * 2
|
|
|
|
RowLayout {
|
|
id: localeLayout
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: Tokens.padding.medium
|
|
anchors.leftMargin: Tokens.padding.largeIncreased
|
|
anchors.rightMargin: Tokens.padding.largeIncreased
|
|
spacing: Tokens.spacing.medium
|
|
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 0
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("System language")
|
|
font: Tokens.font.body.small
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Follows your system locale (%1)").arg(Qt.locale().name)
|
|
color: Colours.palette.m3outline
|
|
font: Tokens.font.label.small
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
text: Qt.locale().nativeLanguageName || Qt.locale().name
|
|
color: Colours.palette.m3onSurfaceVariant
|
|
font: Tokens.font.body.small
|
|
}
|
|
}
|
|
}
|
|
|
|
// Weather
|
|
SectionHeader {
|
|
text: qsTr("Weather")
|
|
}
|
|
|
|
// Location for the weather service. Weather.qml accepts a city name
|
|
// (geocoded) or a "lat,lon" string, and auto-detects via IP when empty.
|
|
ConnectedRect {
|
|
Layout.fillWidth: true
|
|
first: true
|
|
last: true
|
|
implicitHeight: weatherLayout.implicitHeight + weatherLayout.anchors.margins * 2
|
|
|
|
ColumnLayout {
|
|
id: weatherLayout
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: Tokens.padding.medium
|
|
anchors.leftMargin: Tokens.padding.largeIncreased
|
|
anchors.rightMargin: Tokens.padding.largeIncreased
|
|
spacing: Tokens.spacing.small
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Location")
|
|
font: Tokens.font.body.small
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
StyledRect {
|
|
Layout.fillWidth: true
|
|
implicitHeight: locField.implicitHeight + Tokens.padding.medium * 2
|
|
|
|
radius: Tokens.rounding.small
|
|
color: Colours.tPalette.m3surfaceContainerLowest
|
|
border.color: Colours.palette.m3outlineVariant
|
|
|
|
Behavior on border.color {
|
|
CAnim {}
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.IBeamCursor
|
|
onClicked: locField.focus = true
|
|
}
|
|
|
|
StyledTextField {
|
|
id: locField
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.leftMargin: Tokens.padding.large
|
|
anchors.rightMargin: Tokens.padding.large
|
|
|
|
text: GlobalConfig.services.weatherLocation
|
|
placeholderText: qsTr("City name or lat,long — empty = auto (IP)")
|
|
placeholderTextColor: Colours.palette.m3onSurfaceVariant
|
|
color: Colours.palette.m3onSurface
|
|
onEditingFinished: GlobalConfig.services.weatherLocation = text
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.WordWrap
|
|
text: qsTr("Leave empty to detect your location automatically.")
|
|
color: Colours.palette.m3outline
|
|
font: Tokens.font.label.small
|
|
}
|
|
}
|
|
}
|
|
|
|
// Units
|
|
SectionHeader {
|
|
text: qsTr("Units")
|
|
}
|
|
|
|
SelectRow {
|
|
Layout.fillWidth: true
|
|
first: true
|
|
label: qsTr("Temperature")
|
|
subtext: qsTr("Units for weather temperatures")
|
|
menuItems: root.tempItems
|
|
active: root.tempItems[GlobalConfig.services.useFahrenheit ? 1 : 0]
|
|
onSelected: item => GlobalConfig.services.useFahrenheit = root.tempItems.indexOf(item) === 1
|
|
}
|
|
|
|
SelectRow {
|
|
Layout.fillWidth: true
|
|
last: true
|
|
label: qsTr("System temperatures")
|
|
subtext: qsTr("Units for CPU and GPU temperatures")
|
|
menuItems: root.tempItems
|
|
active: root.tempItems[GlobalConfig.services.useFahrenheitPerformance ? 1 : 0]
|
|
onSelected: item => GlobalConfig.services.useFahrenheitPerformance = root.tempItems.indexOf(item) === 1
|
|
}
|
|
|
|
// Time & date
|
|
SectionHeader {
|
|
text: qsTr("Time & date")
|
|
}
|
|
|
|
SelectRow {
|
|
Layout.fillWidth: true
|
|
first: true
|
|
last: true
|
|
label: qsTr("Clock format")
|
|
subtext: qsTr("How times are shown across the shell")
|
|
menuItems: root.clockItems
|
|
active: root.clockItems[GlobalConfig.services.useTwelveHourClock ? 1 : 0]
|
|
onSelected: item => GlobalConfig.services.useTwelveHourClock = root.clockItems.indexOf(item) === 1
|
|
}
|
|
}
|
|
}
|