mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
refactor: common DankTextField widget
This commit is contained in:
196
Widgets/DankTextField.qml
Normal file
196
Widgets/DankTextField.qml
Normal file
@@ -0,0 +1,196 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property alias text: textInput.text
|
||||
property string placeholderText: ""
|
||||
property alias font: textInput.font
|
||||
property alias textColor: textInput.color
|
||||
property alias selectByMouse: textInput.selectByMouse
|
||||
property alias enabled: textInput.enabled
|
||||
property alias echoMode: textInput.echoMode
|
||||
property alias verticalAlignment: textInput.verticalAlignment
|
||||
property alias cursorVisible: textInput.cursorVisible
|
||||
property alias readOnly: textInput.readOnly
|
||||
property alias validator: textInput.validator
|
||||
property alias inputMethodHints: textInput.inputMethodHints
|
||||
property alias maximumLength: textInput.maximumLength
|
||||
// Icon properties
|
||||
property string leftIconName: ""
|
||||
property int leftIconSize: Theme.iconSize
|
||||
property color leftIconColor: Theme.surfaceVariantText
|
||||
property color leftIconFocusedColor: Theme.primary
|
||||
property bool showClearButton: false
|
||||
// Custom properties
|
||||
property color backgroundColor: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
|
||||
property color focusedBorderColor: Theme.primary
|
||||
property color normalBorderColor: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||
property color placeholderColor: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
|
||||
property int borderWidth: 1
|
||||
property int focusedBorderWidth: 2
|
||||
property real cornerRadius: Theme.cornerRadius
|
||||
// Internal padding calculations
|
||||
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
|
||||
|
||||
// Signals
|
||||
signal textEdited()
|
||||
signal editingFinished()
|
||||
signal accepted()
|
||||
signal focusChanged(bool hasFocus)
|
||||
|
||||
// Access to inner TextInput properties via functions
|
||||
function getActiveFocus() {
|
||||
return textInput.activeFocus;
|
||||
}
|
||||
|
||||
function getFocus() {
|
||||
return textInput.focus;
|
||||
}
|
||||
|
||||
function setFocus(value) {
|
||||
textInput.focus = value;
|
||||
}
|
||||
|
||||
// Functions
|
||||
function forceActiveFocus() {
|
||||
textInput.forceActiveFocus();
|
||||
}
|
||||
|
||||
function selectAll() {
|
||||
textInput.selectAll();
|
||||
}
|
||||
|
||||
function clear() {
|
||||
textInput.clear();
|
||||
}
|
||||
|
||||
function paste() {
|
||||
textInput.paste();
|
||||
}
|
||||
|
||||
function copy() {
|
||||
textInput.copy();
|
||||
}
|
||||
|
||||
function cut() {
|
||||
textInput.cut();
|
||||
}
|
||||
|
||||
// Default styling
|
||||
width: 200
|
||||
height: 48
|
||||
radius: cornerRadius
|
||||
color: backgroundColor
|
||||
border.color: textInput.activeFocus ? focusedBorderColor : normalBorderColor
|
||||
border.width: textInput.activeFocus ? focusedBorderWidth : borderWidth
|
||||
|
||||
// Left icon
|
||||
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: true
|
||||
clip: true
|
||||
onTextChanged: root.textEdited()
|
||||
onEditingFinished: root.editingFinished()
|
||||
onAccepted: root.accepted()
|
||||
onActiveFocusChanged: root.focusChanged(activeFocus)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Clear button
|
||||
Rectangle {
|
||||
id: clearButton
|
||||
|
||||
width: 24
|
||||
height: 24
|
||||
radius: 12
|
||||
color: clearArea.containsMouse ? Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) : "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 = "";
|
||||
textInput.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Text {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user