195 lines
7.8 KiB
QML
195 lines
7.8 KiB
QML
/*
|
|
SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
import QtQuick 2.6
|
|
import QtQuick.Window 2.2
|
|
import QtQuick.Controls @QQC2_VERSION@
|
|
import QtQuick.Templates @QQC2_VERSION@ as T
|
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
import org.kde.kconfig 1.0
|
|
import "private" as Private
|
|
import org.kde.kirigami 2.5 as Kirigami
|
|
import "mobiletextselection" as MobileTextSelection
|
|
|
|
T.TextField {
|
|
id: control
|
|
|
|
/**
|
|
* Whether the button to clear the text from TextField is visible.
|
|
* @since 5.73
|
|
*/
|
|
property bool clearButtonShown: false
|
|
|
|
/**
|
|
* Whether to show a button that allows the user to reveal the password in
|
|
* plain text. This only makes sense if the echoMode is set to Password.
|
|
* @since 5.73
|
|
*/
|
|
property bool revealPasswordButtonShown: false
|
|
|
|
// this takes into account kiosk restriction
|
|
readonly property bool __effectiveRevealPasswordButtonShown: revealPasswordButtonShown
|
|
&& KAuthorized.authorize("lineedit_reveal_password")
|
|
&& (echoMode == TextInput.Normal || control.text.length > 0)
|
|
|
|
// Can't guarantee that background will always be present or have the margins property
|
|
readonly property bool __hasBackgroundAndMargins: background && background.hasOwnProperty("margins")
|
|
|
|
/* It might be preferable to do background width OR content width if we
|
|
* want content to stay within the background rather than expanding the
|
|
* control, but this is maintaining compatibility with the pre-existing
|
|
* behavior. Use the following 2 lines if you want text to stay within the
|
|
* background:
|
|
implicitBackgroundWidth + leftInset + rightInset
|
|
|| Math.ceil(Math.max(contentWidth, placeholder.implicitWidth)) + leftPadding + rightPadding
|
|
*/
|
|
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
|
Math.ceil(Math.max(contentWidth, placeholder.implicitWidth)) + leftPadding + rightPadding)
|
|
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
|
contentHeight + topPadding + bottomPadding,
|
|
placeholder.implicitHeight + topPadding + bottomPadding)
|
|
|
|
leftPadding: (__hasBackgroundAndMargins ? background.margins.left : 0) + (control.mirrored ? inlineButtonRow.width : 0)
|
|
topPadding: __hasBackgroundAndMargins ? background.margins.top : 0
|
|
rightPadding: (__hasBackgroundAndMargins ? background.margins.right : 0) + (control.mirrored ? 0 : inlineButtonRow.width)
|
|
bottomPadding: __hasBackgroundAndMargins ? background.margins.bottom : 0
|
|
|
|
PlasmaCore.ColorScope.inherit: !background || !background.visible
|
|
PlasmaCore.ColorScope.colorGroup: PlasmaCore.Theme.ViewColorGroup
|
|
|
|
color: PlasmaCore.Theme.textColor
|
|
placeholderTextColor: PlasmaCore.Theme.disabledTextColor
|
|
selectionColor: PlasmaCore.Theme.highlightColor
|
|
selectedTextColor: PlasmaCore.Theme.highlightedTextColor
|
|
verticalAlignment: TextInput.AlignVCenter
|
|
// Manually setting this fixes alignment in RTL layouts
|
|
horizontalAlignment: TextInput.AlignLeft
|
|
opacity: control.enabled ? 1 : 0.6
|
|
hoverEnabled: !Kirigami.Settings.tabletMode
|
|
|
|
// Work around Qt bug where NativeRendering breaks for non-integer scale factors
|
|
// https://bugreports.qt.io/browse/QTBUG-70481
|
|
renderType: Screen.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering
|
|
|
|
selectByMouse: !Kirigami.Settings.tabletMode
|
|
|
|
cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : null
|
|
Component {
|
|
id: mobileCursor
|
|
MobileTextSelection.MobileCursor {
|
|
target: control
|
|
}
|
|
}
|
|
onFocusChanged: {
|
|
if (focus) {
|
|
MobileTextSelection.MobileTextActionsToolBar.controlRoot = control;
|
|
}
|
|
}
|
|
|
|
onTextChanged: MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = false;
|
|
onPressed: MobileTextSelection.MobileTextActionsToolBar.shouldBeVisible = true;
|
|
|
|
onPressAndHold: {
|
|
if (!Kirigami.Settings.tabletMode) {
|
|
return;
|
|
}
|
|
forceActiveFocus();
|
|
cursorPosition = positionAt(event.x, event.y);
|
|
selectWord();
|
|
}
|
|
MobileTextSelection.MobileCursor {
|
|
target: control
|
|
selectionStartHandle: true
|
|
property var rect: target.positionToRectangle(target.selectionStart)
|
|
//FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling
|
|
x: rect.x + 5
|
|
y: rect.y + 6
|
|
}
|
|
|
|
Label {
|
|
id: placeholder
|
|
enabled: false
|
|
x: control.leftPadding
|
|
y: control.topPadding
|
|
width: control.availableWidth
|
|
height: control.availableHeight
|
|
|
|
text: control.placeholderText
|
|
font: control.font
|
|
color: control.placeholderTextColor
|
|
horizontalAlignment: control.horizontalAlignment
|
|
verticalAlignment: control.verticalAlignment
|
|
visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter)
|
|
elide: Text.ElideRight
|
|
renderType: control.renderType
|
|
}
|
|
|
|
Row {
|
|
id: inlineButtonRow
|
|
anchors.right: control.right
|
|
anchors.rightMargin: control.__hasBackgroundAndMargins ? background.margins.right : 0
|
|
anchors.verticalCenter: control.verticalCenter
|
|
|
|
PlasmaCore.IconItem {
|
|
id: showPasswordButton
|
|
source: __effectiveRevealPasswordButtonShown ? (control.echoMode === TextInput.Normal ? "visibility": "hint") : ""
|
|
height: Math.max(control.height * 0.8, PlasmaCore.Units.iconSizes.small)
|
|
width: height
|
|
opacity: (__effectiveRevealPasswordButtonShown && control.enabled) ? 1 : 0
|
|
visible: opacity > 0
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: PlasmaCore.Units.longDuration
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
enabled: __effectiveRevealPasswordButtonShown
|
|
onClicked: {
|
|
control.echoMode = (control.echoMode == TextInput.Normal ? TextInput.Password : TextInput.Normal)
|
|
control.forceActiveFocus()
|
|
}
|
|
}
|
|
}
|
|
|
|
PlasmaCore.IconItem {
|
|
id: clearButton
|
|
//ltr confusingly refers to the direction of the arrow in the icon, not the text direction which it should be used in
|
|
source: clearButtonShown ? (LayoutMirroring.enabled ? "edit-clear-locationbar-ltr" : "edit-clear-locationbar-rtl") : ""
|
|
height: Math.max(control.height * 0.8, PlasmaCore.Units.iconSizes.small)
|
|
width: height
|
|
opacity: (control.length > 0 && clearButtonShown && control.enabled) ? 1 : 0
|
|
visible: opacity > 0
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: PlasmaCore.Units.longDuration
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
control.clear()
|
|
control.forceActiveFocus()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
background: PlasmaCore.FrameSvgItem {
|
|
implicitWidth: PlasmaCore.Units.gridUnit * 8 + margins.left + margins.right
|
|
implicitHeight: PlasmaCore.Units.gridUnit + margins.top + margins.bottom
|
|
imagePath: "widgets/lineedit"
|
|
prefix: "base"
|
|
|
|
Private.TextFieldFocus {
|
|
state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden")
|
|
anchors.fill: parent
|
|
}
|
|
}
|
|
}
|