NTextInput: improved layout and adapted calling code all over the shell.
This commit is contained in:
parent
e86e7344f3
commit
3f4cec1719
8 changed files with 106 additions and 105 deletions
|
|
@ -301,6 +301,7 @@ NPanel {
|
|||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
padding: Style.marginL * scaling
|
||||
clip: true
|
||||
|
||||
Loader {
|
||||
active: true
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ ColumnLayout {
|
|||
}
|
||||
// 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"
|
||||
|
|
@ -239,8 +237,6 @@ ColumnLayout {
|
|||
|
||||
NTextInput {
|
||||
id: blacklistInput
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
label: "Blacklist player"
|
||||
description: "Substring, e.g. plex, shim, mpv."
|
||||
placeholderText: "type substring and press +"
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ ColumnLayout {
|
|||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -253,7 +252,6 @@ ColumnLayout {
|
|||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +276,7 @@ ColumnLayout {
|
|||
visible: Settings.data.nightLight.enabled
|
||||
NLabel {
|
||||
label: "Intensity"
|
||||
description: "Higher values create warmer light."
|
||||
description: "Higher values create warmer tones."
|
||||
}
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
|
|
@ -305,46 +303,61 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// Temperature settings (inline like schedule)
|
||||
RowLayout {
|
||||
visible: Settings.data.nightLight.enabled
|
||||
Layout.fillWidth: false
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
NText {
|
||||
text: "Low"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
// Temperature
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
NLabel {
|
||||
label: "Color temperature"
|
||||
description: "Select two temperatures in Kelvin"
|
||||
}
|
||||
NTextInput {
|
||||
text: Settings.data.nightLight.lowTemp.toString()
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
Layout.preferredWidth: 100 * scaling
|
||||
onEditingFinished: {
|
||||
var v = parseInt(text)
|
||||
if (!isNaN(v)) {
|
||||
Settings.data.nightLight.lowTemp = Math.max(1000, Math.min(6500, v))
|
||||
NightLightService.apply()
|
||||
|
||||
RowLayout {
|
||||
visible: Settings.data.nightLight.enabled
|
||||
spacing: Style.marginM * scaling
|
||||
Layout.fillWidth: false
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
NText {
|
||||
text: "Low"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
text: Settings.data.nightLight.lowTemp.toString()
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onEditingFinished: {
|
||||
var v = parseInt(text)
|
||||
if (!isNaN(v)) {
|
||||
Settings.data.nightLight.lowTemp = Math.max(1000, Math.min(6500, v))
|
||||
NightLightService.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {}
|
||||
Item {}
|
||||
|
||||
NText {
|
||||
text: "High"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
NTextInput {
|
||||
text: Settings.data.nightLight.highTemp.toString()
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
Layout.preferredWidth: 100 * scaling
|
||||
onEditingFinished: {
|
||||
var v = parseInt(text)
|
||||
if (!isNaN(v)) {
|
||||
Settings.data.nightLight.highTemp = Math.max(1000, Math.min(10000, v))
|
||||
NightLightService.apply()
|
||||
NText {
|
||||
text: "High"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
NTextInput {
|
||||
text: Settings.data.nightLight.highTemp.toString()
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onEditingFinished: {
|
||||
var v = parseInt(text)
|
||||
if (!isNaN(v)) {
|
||||
Settings.data.nightLight.highTemp = Math.max(1000, Math.min(10000, v))
|
||||
NightLightService.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,9 @@ ColumnLayout {
|
|||
|
||||
NTextInput {
|
||||
label: "Profile Picture"
|
||||
description: "Your profile picture displayed in various places throughout the shell."
|
||||
description: "Your profile picture that appears throughout the interface."
|
||||
text: Settings.data.general.avatarImage
|
||||
placeholderText: "/home/user/.face"
|
||||
Layout.fillWidth: true
|
||||
onEditingFinished: {
|
||||
Settings.data.general.avatarImage = text
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ ColumnLayout {
|
|||
onEditingFinished: {
|
||||
Settings.data.screenRecorder.directory = text
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.maximumWidth: 420 * scaling
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ ColumnLayout {
|
|||
|
||||
// Location section
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
NTextInput {
|
||||
|
|
@ -25,6 +26,7 @@ ColumnLayout {
|
|||
LocationService.resetWeather()
|
||||
}
|
||||
}
|
||||
Layout.maximumWidth: 420 * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ ColumnLayout {
|
|||
label: "Wallpaper Directory"
|
||||
description: "Path to your wallpaper directory."
|
||||
text: Settings.data.wallpaper.directory
|
||||
Layout.fillWidth: true
|
||||
onEditingFinished: {
|
||||
Settings.data.wallpaper.directory = text
|
||||
}
|
||||
Layout.maximumWidth: 420 * scaling
|
||||
}
|
||||
|
||||
NDivider {
|
||||
|
|
@ -79,12 +79,7 @@ ColumnLayout {
|
|||
|
||||
NText {
|
||||
// Show friendly H:MM format from current settings
|
||||
text: {
|
||||
const s = Settings.data.wallpaper.randomInterval
|
||||
const h = Math.floor(s / 3600)
|
||||
const m = Math.floor((s % 3600) / 60)
|
||||
return (h > 0 ? (h + "h ") : "") + (m > 0 ? (m + "m") : (h === 0 ? "0m" : ""))
|
||||
}
|
||||
text: Time.formatVagueHumanReadableDuration(Settings.data.wallpaper.randomInterval)
|
||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
||||
}
|
||||
}
|
||||
|
|
@ -284,14 +279,15 @@ ColumnLayout {
|
|||
|
||||
NTextInput {
|
||||
label: "Custom Interval"
|
||||
description: "Enter time as HH:MM (e.g., 1:30)."
|
||||
description: "Enter time as HH:MM (e.g., 01:30)."
|
||||
inputMaxWidth: 100 * scaling
|
||||
text: {
|
||||
const s = Settings.data.wallpaper.randomInterval
|
||||
const h = Math.floor(s / 3600)
|
||||
const m = Math.floor((s % 3600) / 60)
|
||||
return h + ":" + (m < 10 ? ("0" + m) : m)
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
|
||||
onEditingFinished: {
|
||||
const m = text.trim().match(/^(\d{1,2}):(\d{2})$/)
|
||||
if (m) {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import QtQuick.Layouts
|
|||
import qs.Commons
|
||||
import qs.Services
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property string label: ""
|
||||
property string description: ""
|
||||
property bool readOnly: false
|
||||
property bool enabled: true
|
||||
property int inputMaxWidth: 420 * scaling
|
||||
|
||||
property alias text: input.text
|
||||
property alias placeholderText: input.placeholderText
|
||||
|
|
@ -18,61 +19,53 @@ Item {
|
|||
|
||||
signal editingFinished
|
||||
|
||||
// Sizing
|
||||
implicitWidth: Style.sliderWidth * 1.6 * scaling
|
||||
implicitHeight: Style.baseWidgetSize * 2.75 * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
implicitHeight: frame.height
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
visible: root.label !== "" || root.description !== ""
|
||||
}
|
||||
|
||||
NLabel {
|
||||
label: root.label
|
||||
description: root.description
|
||||
// Container
|
||||
Rectangle {
|
||||
id: frame
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: Style.baseWidgetSize * 1.1 * scaling
|
||||
Layout.minimumWidth: 80 * scaling
|
||||
Layout.maximumWidth: root.inputMaxWidth
|
||||
radius: Style.radiusM * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Focus ring
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: frame.radius
|
||||
color: Color.transparent
|
||||
border.color: input.activeFocus ? Color.mSecondary : Color.transparent
|
||||
border.width: input.activeFocus ? Math.max(1, Style.borderS * scaling) : 0
|
||||
}
|
||||
|
||||
// Container
|
||||
Rectangle {
|
||||
id: frame
|
||||
Layout.topMargin: Style.marginXS * scaling
|
||||
implicitWidth: root.width
|
||||
implicitHeight: Style.baseWidgetSize * 1.35 * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginM * scaling
|
||||
anchors.rightMargin: Style.marginM * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
// Focus ring
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: frame.radius
|
||||
color: Color.transparent
|
||||
border.color: input.activeFocus ? Color.mSecondary : Color.transparent
|
||||
border.width: input.activeFocus ? Math.max(1, Style.borderS * scaling) : 0
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginM * scaling
|
||||
anchors.rightMargin: Style.marginM * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
// Optional leading icon slot in the future
|
||||
// Item { Layout.preferredWidth: 0 }
|
||||
TextField {
|
||||
id: input
|
||||
Layout.fillWidth: true
|
||||
echoMode: TextInput.Normal
|
||||
readOnly: root.readOnly
|
||||
enabled: root.enabled
|
||||
color: Color.mOnSurface
|
||||
placeholderTextColor: Color.mOnSurface
|
||||
background: null
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
onEditingFinished: root.editingFinished()
|
||||
// Text changes are observable via the aliased 'text' property (root.text) and its 'textChanged' signal.
|
||||
// No additional callback is invoked here to avoid conflicts with QML's onTextChanged handler semantics.
|
||||
}
|
||||
TextField {
|
||||
id: input
|
||||
Layout.fillWidth: true
|
||||
echoMode: TextInput.Normal
|
||||
readOnly: root.readOnly
|
||||
enabled: root.enabled
|
||||
color: Color.mOnSurface
|
||||
placeholderTextColor: Color.mOnSurfaceVariant
|
||||
background: null
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
onEditingFinished: root.editingFinished()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue