2020-09-23 19:57:54 -04:00
|
|
|
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
2019-12-19 07:46:16 -04:00
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
|
2019-07-13 05:39:01 -04:00
|
|
|
import QtQuick 2.12
|
|
|
|
import QtQuick.Controls 2.12
|
2019-04-26 16:02:20 -04:00
|
|
|
|
|
|
|
TextField {
|
2019-07-18 01:53:28 -04:00
|
|
|
id: field
|
2020-07-12 00:25:57 -04:00
|
|
|
|
|
|
|
property string saveName: ""
|
|
|
|
property var saveId: "ALL"
|
|
|
|
property var saveProperties: ["text"]
|
|
|
|
|
|
|
|
property bool error: false
|
|
|
|
|
|
|
|
property alias radius: textFieldBackground.radius
|
|
|
|
property bool bordered: true
|
|
|
|
|
|
|
|
property color backgroundColor: theme.controls.textField.background
|
|
|
|
property color borderColor: theme.controls.textField.border
|
|
|
|
property color errorBorder: theme.controls.textField.errorBorder
|
|
|
|
|
|
|
|
property color focusedBackgroundColor:
|
|
|
|
theme.controls.textField.focusedBackground
|
|
|
|
property color focusedBorderColor: theme.controls.textField.focusedBorder
|
|
|
|
|
|
|
|
property var disabledText: null
|
|
|
|
property var defaultText: null
|
|
|
|
readonly property bool changed: text !== (defaultText || "")
|
|
|
|
|
|
|
|
property string previousDefaultText: "" // private
|
|
|
|
|
2020-10-31 02:59:56 -04:00
|
|
|
// For rich text, selectedText returns some weird invisible characters
|
|
|
|
// instead of real newlines
|
|
|
|
readonly property string selectedPlainText:
|
|
|
|
selectedText.replace(/[\u2028\u2029]/g, "\n")
|
|
|
|
|
2020-09-03 18:27:31 -04:00
|
|
|
function reset() {
|
|
|
|
clear()
|
|
|
|
text = Qt.binding(() => defaultText || "")
|
|
|
|
}
|
|
|
|
|
2020-09-03 18:30:36 -04:00
|
|
|
function loadState() {
|
|
|
|
if (! text) insertAtCursor(window.getState(this, "text", ""))
|
|
|
|
}
|
|
|
|
|
2020-09-03 18:27:31 -04:00
|
|
|
function insertAtCursor(text) {
|
|
|
|
insert(cursorPosition, text)
|
|
|
|
}
|
2020-07-12 00:25:57 -04:00
|
|
|
|
2020-07-01 12:10:40 -04:00
|
|
|
text: defaultText || ""
|
2019-12-13 06:29:58 -04:00
|
|
|
opacity: enabled ? 1 : theme.disabledElementsOpacity
|
2019-12-10 15:32:42 -04:00
|
|
|
selectByMouse: true
|
2020-11-05 21:16:52 -04:00
|
|
|
activeFocusOnPress: ! readOnly
|
2019-08-30 18:10:25 -04:00
|
|
|
leftPadding: theme.spacing
|
|
|
|
rightPadding: leftPadding
|
|
|
|
topPadding: theme.spacing / 1.5
|
|
|
|
bottomPadding: topPadding
|
|
|
|
|
2019-07-06 17:50:55 -04:00
|
|
|
font.family: theme.fontFamily.sans
|
|
|
|
font.pixelSize: theme.fontSize.normal
|
2019-08-30 17:04:42 -04:00
|
|
|
font.pointSize: -1
|
2019-04-28 15:13:18 -04:00
|
|
|
|
2019-09-07 17:02:09 -04:00
|
|
|
placeholderTextColor: theme.controls.textField.placeholderText
|
|
|
|
color: activeFocus ?
|
|
|
|
theme.controls.textField.focusedText :
|
|
|
|
theme.controls.textField.text
|
|
|
|
|
2019-04-28 15:13:18 -04:00
|
|
|
background: Rectangle {
|
|
|
|
id: textFieldBackground
|
2021-03-02 10:02:29 -04:00
|
|
|
radius: bordered ? theme.radius : 0
|
2019-07-18 01:53:28 -04:00
|
|
|
color: field.activeFocus ? focusedBackgroundColor : backgroundColor
|
2020-06-06 21:42:49 -04:00
|
|
|
|
2019-07-13 20:15:20 -04:00
|
|
|
border.width: bordered ? theme.controls.textField.borderWidth : 0
|
2020-06-06 21:42:49 -04:00
|
|
|
border.color: borderColor
|
|
|
|
|
2020-06-23 08:44:58 -04:00
|
|
|
HBottomFocusLine {
|
|
|
|
show: field.activeFocus
|
2020-06-06 21:42:49 -04:00
|
|
|
borderHeight: theme.controls.textField.borderWidth
|
|
|
|
color: error ? errorBorder : focusedBorderColor
|
|
|
|
}
|
2019-04-28 15:13:18 -04:00
|
|
|
}
|
2019-04-26 16:02:20 -04:00
|
|
|
|
2020-06-25 09:46:26 -04:00
|
|
|
Component.onCompleted: {
|
|
|
|
// Break binding
|
|
|
|
previousDefaultText = previousDefaultText
|
2020-09-03 18:30:36 -04:00
|
|
|
loadState()
|
2019-12-10 17:04:03 -04:00
|
|
|
}
|
2019-12-10 15:32:42 -04:00
|
|
|
|
2019-12-10 16:29:49 -04:00
|
|
|
onTextChanged: window.saveState(this)
|
2019-08-22 14:23:33 -04:00
|
|
|
|
2020-07-01 12:10:40 -04:00
|
|
|
onActiveFocusChanged:
|
|
|
|
if (defaultText !== null) text = text // Break binding
|
2020-06-25 09:46:26 -04:00
|
|
|
|
2020-07-01 12:10:40 -04:00
|
|
|
onDefaultTextChanged: if (defaultText !== null) {
|
2020-06-25 09:46:26 -04:00
|
|
|
if (text === previousDefaultText)
|
|
|
|
text = Qt.binding(() => defaultText)
|
|
|
|
|
|
|
|
previousDefaultText = defaultText
|
|
|
|
}
|
2020-06-03 03:41:30 -04:00
|
|
|
|
2020-08-23 15:41:20 -04:00
|
|
|
onPressed: ev => { if (ev.button === Qt.RightButton) contextMenu.spawn() }
|
|
|
|
onPressAndHold: ev => contextMenu.spawn()
|
|
|
|
|
2020-06-23 06:17:52 -04:00
|
|
|
// Prevent alt/super+any key from typing text
|
2019-08-22 14:23:33 -04:00
|
|
|
Keys.onPressed: if (
|
|
|
|
event.modifiers & Qt.AltModifier ||
|
|
|
|
event.modifiers & Qt.MetaModifier
|
2020-06-23 06:17:52 -04:00
|
|
|
) event.accepted = true
|
|
|
|
|
2020-07-10 00:02:43 -04:00
|
|
|
Keys.onMenuPressed: contextMenu.spawn(false)
|
|
|
|
|
2020-06-23 06:17:52 -04:00
|
|
|
// Prevent leaking arrow presses to parent elements when the carret is at
|
|
|
|
// the beginning or end of the text
|
2020-07-07 10:03:35 -04:00
|
|
|
Keys.onLeftPressed: event.accepted = cursorPosition === 0 && ! selectedText
|
|
|
|
Keys.onRightPressed:
|
|
|
|
event.accepted = cursorPosition === length && ! selectedText
|
2019-12-10 15:32:42 -04:00
|
|
|
|
2019-12-13 06:29:58 -04:00
|
|
|
Binding on color {
|
|
|
|
value: "transparent"
|
|
|
|
when: disabledText !== null && ! field.enabled
|
|
|
|
}
|
|
|
|
|
|
|
|
Binding on placeholderTextColor {
|
|
|
|
value: "transparent"
|
|
|
|
when: disabledText !== null && ! field.enabled
|
|
|
|
}
|
|
|
|
|
2020-03-17 17:41:15 -04:00
|
|
|
Binding on implicitHeight {
|
|
|
|
value: disabledTextLabel.implicitHeight
|
2020-05-29 14:43:30 -04:00
|
|
|
when: disabledText !== null && ! field.enabled
|
2020-03-17 17:41:15 -04:00
|
|
|
}
|
|
|
|
|
2019-12-16 04:42:41 -04:00
|
|
|
Behavior on opacity { HNumberAnimation {} }
|
2019-12-13 06:29:58 -04:00
|
|
|
Behavior on color { HColorAnimation {} }
|
|
|
|
Behavior on placeholderTextColor { HColorAnimation {} }
|
|
|
|
|
|
|
|
HLabel {
|
2020-03-17 17:41:15 -04:00
|
|
|
id: disabledTextLabel
|
2019-12-13 06:29:58 -04:00
|
|
|
anchors.fill: parent
|
|
|
|
visible: opacity > 0
|
|
|
|
opacity: disabledText !== null && parent.enabled ? 0 : 1
|
|
|
|
text: disabledText || ""
|
|
|
|
|
|
|
|
leftPadding: parent.leftPadding
|
|
|
|
rightPadding: parent.rightPadding
|
|
|
|
topPadding: parent.topPadding
|
|
|
|
bottomPadding: parent.bottomPadding
|
|
|
|
|
2020-03-17 17:41:15 -04:00
|
|
|
wrapMode:
|
2020-07-17 01:45:02 -04:00
|
|
|
parent.wrapMode === TextField.Wrap ? HLabel.Wrap :
|
|
|
|
parent.wrapMode === TextField.WordWrap ? HLabel.WordWrap :
|
|
|
|
parent.wrapMode === TextField.WrapAnywhere ? HLabel.WrapAnywhere :
|
2020-03-17 17:41:15 -04:00
|
|
|
Text.NoWrap
|
|
|
|
|
2019-12-13 06:29:58 -04:00
|
|
|
font.family: parent.font.family
|
|
|
|
font.pixelSize: parent.font.pixelSize
|
|
|
|
|
2019-12-16 04:42:41 -04:00
|
|
|
Behavior on opacity { HNumberAnimation {} }
|
2019-12-13 06:29:58 -04:00
|
|
|
}
|
2020-07-10 00:02:43 -04:00
|
|
|
|
|
|
|
HTextContextMenu { id: contextMenu }
|
2019-04-26 16:02:20 -04:00
|
|
|
}
|