1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00
Files
DankMaterialShell/quickshell/Widgets/DankTextField.qml
2025-11-12 17:18:45 -05:00

205 lines
6.6 KiB
QML

import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
StyledRect {
id: root
activeFocusOnTab: true
KeyNavigation.tab: keyNavigationTab
KeyNavigation.backtab: keyNavigationBacktab
onActiveFocusChanged: {
if (activeFocus) {
textInput.forceActiveFocus()
}
}
property alias text: textInput.text
property string placeholderText: ""
property alias font: textInput.font
property alias textColor: textInput.color
property alias enabled: textInput.enabled
property alias echoMode: textInput.echoMode
property alias validator: textInput.validator
property alias maximumLength: textInput.maximumLength
property string leftIconName: ""
property int leftIconSize: Theme.iconSize
property color leftIconColor: Theme.surfaceVariantText
property color leftIconFocusedColor: Theme.primary
property bool showClearButton: false
property color backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
property color focusedBorderColor: Theme.primary
property color normalBorderColor: Theme.outlineMedium
property color placeholderColor: Theme.outlineButton
property int borderWidth: 1
property int focusedBorderWidth: 2
property real cornerRadius: Theme.cornerRadius
readonly property real leftPadding: Theme.spacingM + (leftIconName ? leftIconSize + Theme.spacingM : 0)
readonly property real rightPadding: Theme.spacingM + (showClearButton && text.length > 0 ? 24 + Theme.spacingM : 0)
property real topPadding: Theme.spacingM
property real bottomPadding: Theme.spacingM
property bool ignoreLeftRightKeys: false
property bool ignoreTabKeys: false
property var keyForwardTargets: []
property Item keyNavigationTab: null
property Item keyNavigationBacktab: null
signal textEdited
signal editingFinished
signal accepted
signal focusStateChanged(bool hasFocus)
function getActiveFocus() {
return textInput.activeFocus
}
function setFocus(value) {
textInput.focus = value
}
function forceActiveFocus() {
textInput.forceActiveFocus()
}
function selectAll() {
textInput.selectAll()
}
function clear() {
textInput.clear()
}
function insertText(str) {
textInput.insert(textInput.cursorPosition, str)
}
width: 200
height: 48
radius: cornerRadius
color: backgroundColor
border.color: textInput.activeFocus ? focusedBorderColor : normalBorderColor
border.width: textInput.activeFocus ? focusedBorderWidth : borderWidth
DankIcon {
id: leftIcon
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
name: leftIconName
size: leftIconSize
color: textInput.activeFocus ? leftIconFocusedColor : leftIconColor
visible: leftIconName !== ""
}
TextInput {
id: textInput
anchors.fill: parent
anchors.leftMargin: root.leftPadding
anchors.rightMargin: root.rightPadding
anchors.topMargin: root.topPadding
anchors.bottomMargin: root.bottomPadding
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
verticalAlignment: TextInput.AlignVCenter
selectByMouse: !root.ignoreLeftRightKeys
clip: true
activeFocusOnTab: true
KeyNavigation.tab: root.keyNavigationTab
KeyNavigation.backtab: root.keyNavigationBacktab
onTextChanged: root.textEdited()
onEditingFinished: root.editingFinished()
onAccepted: root.accepted()
onActiveFocusChanged: root.focusStateChanged(activeFocus)
Keys.forwardTo: root.keyForwardTargets
Keys.onLeftPressed: event => {
if (root.ignoreLeftRightKeys) {
event.accepted = true
} else {
// Allow normal TextInput cursor movement
event.accepted = false
}
}
Keys.onRightPressed: event => {
if (root.ignoreLeftRightKeys) {
event.accepted = true
} else {
event.accepted = false
}
}
Keys.onPressed: event => {
if (root.ignoreTabKeys && (event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab)) {
event.accepted = false
for (var i = 0; i < root.keyForwardTargets.length; i++) {
if (root.keyForwardTargets[i]) {
root.keyForwardTargets[i].Keys.pressed(event)
}
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.IBeamCursor
acceptedButtons: Qt.NoButton
}
}
StyledRect {
id: clearButton
width: 24
height: 24
radius: 12
color: clearArea.containsMouse ? Theme.outlineStrong : "transparent"
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
visible: showClearButton && text.length > 0
DankIcon {
anchors.centerIn: parent
name: "close"
size: 16
color: clearArea.containsMouse ? Theme.outline : Theme.surfaceVariantText
}
MouseArea {
id: clearArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
textInput.text = ""
}
}
}
StyledText {
id: placeholderLabel
anchors.fill: textInput
text: root.placeholderText
font: textInput.font
color: placeholderColor
verticalAlignment: textInput.verticalAlignment
visible: textInput.text.length === 0 && !textInput.activeFocus
elide: Text.ElideRight
}
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Behavior on border.width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}