NCombox + NTextInput proper label/description support

+ Associated changes in window settings
This commit is contained in:
quadbyte 2025-08-12 18:34:26 -04:00
parent 3997a369ec
commit 0417590221
8 changed files with 111 additions and 125 deletions

View file

@ -146,6 +146,8 @@ NLoader {
} }
NComboBox { NComboBox {
label: "Animal"
description: "What's your favorite"
optionsKeys: ["cat", "dog", "bird", "monkey", "fish", "turtle", "elephant", "tiger"] optionsKeys: ["cat", "dog", "bird", "monkey", "fish", "turtle", "elephant", "tiger"]
optionsLabels: ["Cat", "Dog", "Bird", "Monkey", "Fish", "Turtle", "Elephant", "Tiger"] optionsLabels: ["Cat", "Dog", "Bird", "Monkey", "Fish", "Turtle", "Elephant", "Tiger"]
currentKey: "cat" currentKey: "cat"
@ -169,14 +171,16 @@ NLoader {
} }
NTextInput { NTextInput {
label: "Input label"
description: "A cool description"
text: "Type anything" text: "Type anything"
Layout.fillWidth: true Layout.fillWidth: true
onEditingFinished: { onEditingFinished: {
} }
NDivider { }
Layout.fillWidth: true NDivider {
} Layout.fillWidth: true
} }
} }

View file

@ -58,26 +58,15 @@ ColumnLayout {
borderColor: Colors.accentPrimary borderColor: Colors.accentPrimary
borderWidth: Math.max(1, Style.borderMedium) borderWidth: Math.max(1, Style.borderMedium)
} }
ColumnLayout {
NTextInput {
label: "Profile Picture"
description: "Your profile picture displayed in various places throughout the shell"
text: Settings.data.general.avatarImage
placeholderText: "/home/user/.face"
Layout.fillWidth: true Layout.fillWidth: true
spacing: Style.marginTiny * scaling onEditingFinished: {
NText { Settings.data.general.avatarImage = text
text: "Profile Picture"
color: Colors.textPrimary
font.weight: Style.fontWeightBold
}
NText {
text: "Your profile picture displayed in various places throughout the shell"
color: Colors.textSecondary
font.pointSize: Style.fontSizeSmall * scaling
}
NTextInput {
text: Settings.data.general.avatarImage
placeholderText: "/home/user/.face"
Layout.fillWidth: true
onEditingFinished: {
Settings.data.general.avatarImage = text
}
} }
} }
} }

View file

@ -16,8 +16,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
padding: 16 padding: Style.marginMedium * scaling
rightPadding: 12
clip: true clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded ScrollBar.vertical.policy: ScrollBar.AsNeeded
@ -32,46 +31,31 @@ ColumnLayout {
} }
ColumnLayout { ColumnLayout {
spacing: 4 spacing: Style.marginLarge * scaling
Layout.fillWidth: true Layout.fillWidth: true
NText { NText {
text: "Network Settings" text: "Network Settings"
font.pointSize: 18 font.pointSize: Style.fontSizeXL * scaling
font.weight: Style.fontWeightBold font.weight: Style.fontWeightBold
color: Colors.textPrimary color: Colors.textPrimary
Layout.bottomMargin: 8
} }
// Network interfaces section NToggle {
ColumnLayout { label: "WiFi Enabled"
spacing: 8 description: "Enable WiFi connectivity"
Layout.fillWidth: true value: Settings.data.network.wifiEnabled
Layout.topMargin: 8 onToggled: function (newValue) {
Settings.data.network.wifiEnabled = newValue
NText {
text: "Network Interfaces"
font.pointSize: 13
font.weight: Style.fontWeightBold
color: Colors.textPrimary
} }
}
NToggle { NToggle {
label: "WiFi Enabled" label: "Bluetooth Enabled"
description: "Enable WiFi connectivity" description: "Enable Bluetooth connectivity"
value: Settings.data.network.wifiEnabled value: Settings.data.network.bluetoothEnabled
onToggled: function (newValue) { onToggled: function (newValue) {
Settings.data.network.wifiEnabled = newValue Settings.data.network.bluetoothEnabled = newValue
}
}
NToggle {
label: "Bluetooth Enabled"
description: "Enable Bluetooth connectivity"
value: Settings.data.network.bluetoothEnabled
onToggled: function (newValue) {
Settings.data.network.bluetoothEnabled = newValue
}
} }
} }
} }

View file

@ -33,7 +33,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
NText { NText {
text: "Screen Recording" text: "Recording"
font.pointSize: Style.fontSizeXL * scaling font.pointSize: Style.fontSizeXL * scaling
font.weight: Style.fontWeightBold font.weight: Style.fontWeightBold
color: Colors.textPrimary color: Colors.textPrimary
@ -46,24 +46,10 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Style.marginSmall * scaling Layout.topMargin: Style.marginSmall * scaling
ColumnLayout {
spacing: Style.marginTiny * scaling
NText {
text: "Output Directory"
font.weight: Style.fontWeightBold
color: Colors.textPrimary
}
NText {
text: "Directory where screen recordings will be saved"
font.pointSize: Style.fontSizeSmall * scaling
color: Colors.textSecondary
wrapMode: Text.WordWrap
}
}
NTextInput { NTextInput {
label: "Output Directory"
description: "Directory where screen recordings will be saved"
placeholderText: "/home/xxx/Videos"
text: Settings.data.screenRecorder.directory text: Settings.data.screenRecorder.directory
onEditingFinished: { onEditingFinished: {
Settings.data.screenRecorder.directory = text Settings.data.screenRecorder.directory = text

View file

@ -47,8 +47,10 @@ ColumnLayout {
Layout.topMargin: Style.marginSmall * scaling Layout.topMargin: Style.marginSmall * scaling
NTextInput { NTextInput {
label: "Location name"
description: "Choose a known location near you"
text: Settings.data.location.name text: Settings.data.location.name
placeholderText: "Enter city name" placeholderText: "Enter the location name"
Layout.fillWidth: true Layout.fillWidth: true
onEditingFinished: { onEditingFinished: {
Settings.data.location.name = text Settings.data.location.name = text
@ -64,7 +66,7 @@ ColumnLayout {
// Time section // Time section
ColumnLayout { ColumnLayout {
spacing: Style.marginLarge * scaling spacing: Style.marginLarge * scaling
Layout.fillWidth: true Layout.fillWidth: true
NText { NText {

View file

@ -14,8 +14,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
padding: 16 padding: Style.marginMedium * scaling
rightPadding: 12
clip: true clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded ScrollBar.vertical.policy: ScrollBar.AsNeeded

View file

@ -59,7 +59,7 @@ ColumnLayout {
implicitWidth: 120 * scaling implicitWidth: 120 * scaling
implicitHeight: preferredHeight implicitHeight: preferredHeight
color: Colors.surfaceVariant color: Colors.surfaceVariant
border.color: root.activeFocus ? Colors.hover : Colors.outline border.color: combo.activeFocus ? Colors.hover : Colors.outline
border.width: Math.max(1, Style.borderThin * scaling) border.width: Math.max(1, Style.borderThin * scaling)
radius: Style.radiusMedium * scaling radius: Style.radiusMedium * scaling
} }
@ -69,7 +69,6 @@ ColumnLayout {
leftPadding: Style.marginLarge * scaling leftPadding: Style.marginLarge * scaling
rightPadding: combo.indicator.width + Style.marginLarge * scaling rightPadding: combo.indicator.width + Style.marginLarge * scaling
font.pointSize: Style.fontSizeMedium * scaling font.pointSize: Style.fontSizeMedium * scaling
font.weight: Style.fontWeightBold
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
text: { text: {
@ -79,16 +78,16 @@ ColumnLayout {
// Drop down indicator // Drop down indicator
indicator: NText { indicator: NText {
x: root.width - width - Style.marginMedium * scaling x: combo.width - width - Style.marginMedium * scaling
y: root.topPadding + (root.availableHeight - height) / 2 y: combo.topPadding + (combo.availableHeight - height) / 2
text: "arrow_drop_down" text: "arrow_drop_down"
font.family: "Material Symbols Outlined" font.family: "Material Symbols Outlined"
font.pointSize: Style.fontSizeXL * scaling font.pointSize: Style.fontSizeXL * scaling
} }
popup: Popup { popup: Popup {
y: root.height y: combo.height
width: root.width width: combo.width
implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginMedium * scaling * 2) implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginMedium * scaling * 2)
padding: Style.marginMedium * scaling padding: Style.marginMedium * scaling
@ -109,8 +108,8 @@ ColumnLayout {
} }
delegate: ItemDelegate { delegate: ItemDelegate {
width: root.width width: combo.width
highlighted: root.highlightedIndex === index highlighted: combo.highlightedIndex === index
contentItem: NText { contentItem: NText {
text: { text: {
@ -123,7 +122,7 @@ ColumnLayout {
} }
background: Rectangle { background: Rectangle {
width: root.width - Style.marginMedium * scaling * 3 width: combo.width - Style.marginMedium * scaling * 3
color: highlighted ? Colors.hover : "transparent" color: highlighted ? Colors.hover : "transparent"
radius: Style.radiusSmall * scaling radius: Style.radiusSmall * scaling
} }

View file

@ -7,58 +7,81 @@ Item {
id: root id: root
readonly property real scaling: Scaling.scale(screen) readonly property real scaling: Scaling.scale(screen)
property string label: ""
// API property string description: ""
property alias text: input.text
property alias placeholderText: input.placeholderText
property bool readOnly: false property bool readOnly: false
property bool enabled: true property bool enabled: true
property alias text: input.text
property alias placeholderText: input.placeholderText
signal editingFinished signal editingFinished
// Sizing // Sizing
implicitWidth: 320 * scaling implicitWidth: 320 * scaling
implicitHeight: Style.baseWidgetSize * 1.25 * scaling implicitHeight: Style.baseWidgetSize * 2.75 * scaling
// Container ColumnLayout {
Rectangle { spacing: Style.marginTiniest * scaling
id: frame Layout.fillWidth: true
anchors.fill: parent
radius: Style.radiusMedium * scaling
color: Colors.surfaceVariant
border.color: Colors.outline
border.width: Math.max(1, Style.borderThin * scaling)
// Focus ring NText {
Rectangle { text: label
anchors.fill: parent font.pointSize: Style.fontSizeMedium * scaling
radius: frame.radius font.weight: Style.fontWeightBold
color: "transparent" color: Colors.textPrimary
border.color: input.activeFocus ? Colors.hover : "transparent"
border.width: input.activeFocus ? Math.max(1, Style.borderThin * scaling) : 0
} }
RowLayout { NText {
anchors.fill: parent text: description
anchors.leftMargin: Style.marginMedium * scaling font.pointSize: Style.fontSizeSmall * scaling
anchors.rightMargin: Style.marginMedium * scaling color: Colors.textSecondary
spacing: Style.marginSmall * scaling wrapMode: Text.WordWrap
Layout.fillWidth: true
}
// Optional leading icon slot in the future // Container
// Item { Layout.preferredWidth: 0 } Rectangle {
TextField { id: frame
id: input Layout.topMargin: Style.marginTiny * scaling
Layout.fillWidth: true implicitWidth: root.width
echoMode: TextInput.Normal implicitHeight: Style.baseWidgetSize * 1.35 * scaling
readOnly: root.readOnly radius: Style.radiusMedium * scaling
enabled: root.enabled color: Colors.surfaceVariant
color: Colors.textPrimary border.color: Colors.outline
placeholderTextColor: Colors.textSecondary border.width: Math.max(1, Style.borderThin * scaling)
background: null
font.pointSize: Style.fontSizeSmall * scaling // Focus ring
onEditingFinished: root.editingFinished() Rectangle {
// Text changes are observable via the aliased 'text' property (root.text) and its 'textChanged' signal. anchors.fill: parent
// No additional callback is invoked here to avoid conflicts with QML's onTextChanged handler semantics. radius: frame.radius
color: "transparent"
border.color: input.activeFocus ? Colors.hover : "transparent"
border.width: input.activeFocus ? Math.max(1, Style.borderThin * scaling) : 0
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: Style.marginMedium * scaling
anchors.rightMargin: Style.marginMedium * scaling
spacing: Style.marginSmall * 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: Colors.textPrimary
placeholderTextColor: Colors.textSecondary
background: null
font.pointSize: Style.fontSizeSmall * 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.
}
} }
} }
} }