From 1a81ab0924740eb1b466aae4d861cb2369e9d5fa Mon Sep 17 00:00:00 2001 From: "B.Melnik" Date: Mon, 28 Jun 2021 16:36:51 +0300 Subject: [PATCH] feat(Controls): introduce StatusBaseInput Usage: The same interface like TextField Closes: #106 --- ui/StatusQ/sandbox/Controls.qml | 30 ++++ .../src/StatusQ/Controls/StatusBaseInput.qml | 146 ++++++++++++++++++ ui/StatusQ/src/StatusQ/Controls/qmldir | 1 + ui/StatusQ/statusq.qrc | 1 + 4 files changed, 178 insertions(+) create mode 100644 ui/StatusQ/src/StatusQ/Controls/StatusBaseInput.qml diff --git a/ui/StatusQ/sandbox/Controls.qml b/ui/StatusQ/sandbox/Controls.qml index 1895ca69cb..0cd2c78a9e 100644 --- a/ui/StatusQ/sandbox/Controls.qml +++ b/ui/StatusQ/sandbox/Controls.qml @@ -5,6 +5,8 @@ import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 +import Sandbox 0.1 + GridLayout { columns: 6 columnSpacing: 5 @@ -141,4 +143,32 @@ GridLayout { to: 100 value: 40 } + + StatusBaseInput { + placeholderText: "One line" + } + + StatusBaseInput { + multiline: true + placeholderText: "Multiline" + } + + StatusBaseInput { + multiline: true + placeholderText: "Multiline with static height" + implicitHeight: 100 + } + + Item { + implicitHeight: 300 + implicitWidth: 300 + + StatusBaseInput { + anchors.centerIn: parent + multiline: true + placeholderText: "Multiline with max/min" + minimumHeight: 80 + maximumHeight: 200 + } + } } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusBaseInput.qml b/ui/StatusQ/src/StatusQ/Controls/StatusBaseInput.qml new file mode 100644 index 0000000000..ae8e4f875c --- /dev/null +++ b/ui/StatusQ/src/StatusQ/Controls/StatusBaseInput.qml @@ -0,0 +1,146 @@ +import QtQuick 2.14 + +import QtQuick.Controls 2.14 as QC + +import StatusQ.Controls 0.1 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + + +Item { + id: statusBaseInput + + property bool multiline: false + + property bool clearable: false + + property alias inputMethodHints: edit.inputMethodHints + + property alias selectedText: edit.selectedText + property alias selectedTextColor: edit.selectedTextColor + property alias selectionStart: edit.selectionStart + property alias selectionEnd: edit.selectionEnd + + property alias color: edit.color + property alias font: edit.font + property alias verticalAlignmet: edit.verticalAlignment + property alias horizontalAlignment: edit.horizontalAlignment + + property alias placeholderText: placeholder.text + property alias placeholderTextColor: placeholder.color + property alias placeholderFont: placeholder.font + + property real leftPadding: 16 + property real rightPadding: 16 + property real topPadding: 11 + property real bottomPadding: 11 + + property real minimumHeight: 0 + property real maximumHeight: 0 + + implicitWidth: 200 + implicitHeight: multiline ? Math.max(edit.implicitHeight + topPadding + bottomPadding, 40) : 40 + + Rectangle { + width: parent.width + height: maximumHeight != 0 ? Math.min( + minimumHeight != 0 ? Math.max(statusBaseInput.implicitHeight, minimumHeight) + : implicitHeight, + maximumHeight) + : parent.height + color: Theme.palette.baseColor2 + radius: 8 + + clip: true + + Flickable { + id: flick + + anchors.fill: parent + anchors.leftMargin: statusBaseInput.leftPadding + anchors.rightMargin: statusBaseInput.rightPadding + clearable ? clearButtton.width : 0 + anchors.topMargin: statusBaseInput.topPadding + anchors.bottomMargin: statusBaseInput.bottomPadding + contentWidth: edit.paintedWidth + contentHeight: edit.paintedHeight + clip: true + + QC.ScrollBar.vertical: QC.ScrollBar { interactive: multiline } + + + function ensureVisible(r) { + if (contentX >= r.x) + contentX = r.x; + else if (contentX+width <= r.x+r.width) + contentX = r.x+r.width-width; + if (contentY >= r.y) + contentY = r.y; + else if (contentY+height <= r.y+r.height) + contentY = r.y+r.height-height; + } + + + + TextEdit { + id: edit + width: flick.width + selectByMouse: true + anchors.verticalCenter: parent.verticalCenter + focus: true + + font.pixelSize: 15 + font.family: Theme.palette.baseFont.name + color: Theme.palette.directColor1 + + onCursorRectangleChanged: flick.ensureVisible(cursorRectangle) + wrapMode: TextEdit.NoWrap + + Keys.onReturnPressed: { + if (multiline) { + event.accepted = false + } else { + event.accepted = true + } + } + + Keys.onEnterPressed: { + if (multiline) { + event.accepted = false + } else { + event.accepted = true + } + } + + StatusBaseText { + id: placeholder + visible: edit.text.length === 0 + anchors.left: parent.left + anchors.right: parent.right + font.pixelSize: 15 + + elide: StatusBaseText.ElideRight + font.family: Theme.palette.baseFont.name + color: Theme.palette.baseColor1 + } + } + } // Flickable + } // Rectangle + + StatusFlatRoundButton { + id: clearButtton + visible: edit.text.length != 0 && statusBaseInput.clearable && !statusBaseInput.multiline + anchors.right: parent.right + anchors.rightMargin: 11 + anchors.verticalCenter: parent.verticalCenter + type: StatusFlatRoundButton.Type.Secondary + width: 14 + height: 14 + icon.name: "clear" + icon.width: 14 + icon.height: 14 + onClicked: { + edit.clear() + } + } + +} diff --git a/ui/StatusQ/src/StatusQ/Controls/qmldir b/ui/StatusQ/src/StatusQ/Controls/qmldir index 9c7612faf6..f7e1510061 100644 --- a/ui/StatusQ/src/StatusQ/Controls/qmldir +++ b/ui/StatusQ/src/StatusQ/Controls/qmldir @@ -14,3 +14,4 @@ StatusSwitch 0.1 StatusSwitch.qml StatusRadioButton 0.1 StatusRadioButton.qml StatusCheckBox 0.1 StatusCheckBox.qml StatusSlider 0.1 StatusSlider.qml +StatusBaseInput 0.1 StatusBaseInput.qml diff --git a/ui/StatusQ/statusq.qrc b/ui/StatusQ/statusq.qrc index da7ea46073..5d1d7a295a 100644 --- a/ui/StatusQ/statusq.qrc +++ b/ui/StatusQ/statusq.qrc @@ -241,6 +241,7 @@ src/assets/img/icons/activity.svg src/StatusQ/Components/StatusChatListCategoryItem.qml src/StatusQ/Components/StatusChatListCategory.qml + src/StatusQ/Controls/StatusBaseInput.qml src/StatusQ/Controls/StatusChatListCategoryItemButton.qml src/StatusQ/Components/StatusChatList.qml src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml