aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Gruendl <henning.gruendl@qt.io>2020-07-16 13:01:41 +0200
committerHenning Gründl <henning.gruendl@qt.io>2020-08-03 12:57:01 +0000
commit9f2bb4abaf7f99f741bb422135f651d429bf89d3 (patch)
treef2fca9c5548e49b0f3e09b5593d36e4883ee39a5
parentd1aabbe262589fab96a9cf1fa98aa1c7e63e4b5b (diff)
QmlDesigner: Fix ExpressionTextField popup
Fix the ListView/Popup which is shown on the ExpressionTextField when requesting auto completion. * Fix key behavior of the auto completion list * Adapt to the look and feel of the property editor * Fix size and position of the TextField and the overlayed Label Task-number: QDS-2561 Change-Id: Ie8df6a2960b1c273600543532f0a136eb0c542b5 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml22
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml29
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExpressionTextField.qml229
3 files changed, 197 insertions, 83 deletions
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
index 5f989a672f..9118cae9be 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
@@ -66,15 +66,12 @@ Rectangle {
RoundedPanel {
Layout.fillWidth: true
- height: 24
+ height: StudioTheme.Values.height
Label {
- x: 6
anchors.fill: parent
- anchors.leftMargin: 16
-
+ anchors.leftMargin: StudioTheme.Values.inputHorizontalPadding
text: backendValues.className.value
- verticalAlignment: Text.AlignVCenter
}
ToolTipArea {
anchors.fill: parent
@@ -88,10 +85,10 @@ Rectangle {
}
ExpressionTextField {
- z: 2
id: typeLineEdit
+ z: 2
completeOnlyTypes: true
-
+ replaceCurrentTextByCompletion: true
anchors.fill: parent
visible: false
@@ -107,11 +104,18 @@ Rectangle {
typeLineEdit.blockEditingFinished = true
- if (visible)
+ if (typeLineEdit.visible)
changeTypeName(typeLineEdit.text.trim())
- visible = false
+ typeLineEdit.visible = false
typeLineEdit.blockEditingFinished = false
+
+ typeLineEdit.completionList.model = null
+ }
+
+ onRejected: {
+ typeLineEdit.visible = false
+ typeLineEdit.completionList.model = null
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml
index 3d8678e112..78d99f4d28 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/QtObjectPane.qml
@@ -63,15 +63,12 @@ Rectangle {
RoundedPanel {
Layout.fillWidth: true
- height: 24
+ height: StudioTheme.Values.height
Label {
- x: 6
anchors.fill: parent
- anchors.leftMargin: 16
-
+ anchors.leftMargin: StudioTheme.Values.inputHorizontalPadding
text: backendValues.className.value
- verticalAlignment: Text.AlignVCenter
}
ToolTipArea {
anchors.fill: parent
@@ -88,7 +85,7 @@ Rectangle {
z: 2
id: typeLineEdit
completeOnlyTypes: true
-
+ replaceCurrentTextByCompletion: true
anchors.fill: parent
visible: false
@@ -96,10 +93,26 @@ Rectangle {
showButtons: false
fixedSize: true
+ property bool blockEditingFinished: false
+
onEditingFinished: {
- if (visible)
+ if (typeLineEdit.blockEditingFinished)
+ return
+
+ typeLineEdit.blockEditingFinished = true
+
+ if (typeLineEdit.visible)
changeTypeName(typeLineEdit.text.trim())
- visible = false
+ typeLineEdit.visible = false
+
+ typeLineEdit.blockEditingFinished = false
+
+ typeLineEdit.completionList.model = null
+ }
+
+ onRejected: {
+ typeLineEdit.visible = false
+ typeLineEdit.completionList.model = null
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExpressionTextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExpressionTextField.qml
index e0de0d3b88..53557780d1 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExpressionTextField.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExpressionTextField.qml
@@ -23,13 +23,14 @@
**
****************************************************************************/
-import QtQuick 2.1
-import "Constants.js" as Constants
-import StudioControls 1.0 as StudioControls
+import QtQuick 2.15
+import QtQuick.Window 2.15
+import QtQuick.Controls 2.15
import QtQuickDesignerTheme 1.0
+import StudioControls 1.0 as StudioControls
+import StudioTheme 1.0 as StudioTheme
StudioControls.TextField {
-
id: textField
signal rejected
@@ -38,103 +39,199 @@ StudioControls.TextField {
actionIndicator.visible: false
property bool completeOnlyTypes: false
-
- property bool completionActive: listView.count > 0
+ property bool completionActive: listView.model !== null
property bool dotCompletion: false
property int dotCursorPos: 0
property string prefix
-
property alias showButtons: buttonrow.visible
-
property bool fixedSize: false
+ property bool replaceCurrentTextByCompletion: false
- function commitCompletion() {
- var cursorPos = textField.cursorPosition
+ property alias completionList: listView
- var string = textField.text
- var before = string.slice(0, cursorPos - textField.prefix.length)
- var after = string.slice(cursorPos)
-
- textField.text = before + listView.currentItem.text + after
-
- textField.cursorPosition = cursorPos + listView.currentItem.text.length - prefix.length
+ function commitCompletion() {
+ if (replaceCurrentTextByCompletion) {
+ textField.text = listView.currentItem.text
+ } else {
+ var cursorPos = textField.cursorPosition
+ var string = textField.text
+ var before = string.slice(0, cursorPos - textField.prefix.length)
+ var after = string.slice(cursorPos)
+ textField.text = before + listView.currentItem.text + after
+ textField.cursorPosition = cursorPos + listView.currentItem.text.length - prefix.length
+ }
listView.model = null
}
- ListView {
- id: listView
+ Popup {
+ id: textFieldPopup
+ x: textField.x
+ y: textField.height - StudioTheme.Values.border
+ width: textField.width
+ // TODO Setting the height on the popup solved the problem with the popup of height 0,
+ // but it has the problem that it sometimes extend over the border of the actual window
+ // and is then cut off.
+ height: Math.min(contentItem.implicitHeight + textFieldPopup.topPadding + textFieldPopup.bottomPadding,
+ textField.Window.height - topMargin - bottomMargin,
+ StudioTheme.Values.maxComboBoxPopupHeight)
+ padding: StudioTheme.Values.border
+ margins: 0 // If not defined margin will be -1
+ closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnPressOutsideParent
+ | Popup.CloseOnEscape | Popup.CloseOnReleaseOutside
+ | Popup.CloseOnReleaseOutsideParent
- clip: true
- cacheBuffer: 0
- snapMode: ListView.SnapToItem
- boundsBehavior: Flickable.StopAtBounds
visible: textField.completionActive
- delegate: Text {
- text: modelData
- color: Theme.color(Theme.PanelTextColorLight)
- Rectangle {
- visible: index === listView.currentIndex
- z: -1
- anchors.fill: parent
- color: Theme.qmlDesignerBackgroundColorDarkAlternate()
+
+ onClosed: listView.model = null
+
+ contentItem: ListView {
+ id: listView
+ clip: true
+ implicitHeight: contentHeight
+ boundsBehavior: Flickable.StopAtBounds
+ ScrollBar.vertical: StudioControls.ScrollBar {
+ id: popupScrollBar
}
- }
- anchors.top: parent.top
- anchors.topMargin: 26
- anchors.bottomMargin: textField.fixedSize ? -180 : 12
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- width: 200
- spacing: 2
- children: [
- Rectangle {
- visible: textField.fixedSize
- anchors.fill: parent
- color: Theme.qmlDesignerBackgroundColorDarker()
- border.color: Theme.qmlDesignerBorderColor()
- anchors.rightMargin: 12
- z: -1
+ model: null
+
+ delegate: ItemDelegate {
+ id: myItemDelegate
+
+ width: textFieldPopup.width - textFieldPopup.leftPadding - textFieldPopup.rightPadding
+ - (popupScrollBar.visible ? popupScrollBar.contentItem.implicitWidth
+ + 2 : 0) // TODO Magic number
+ height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
+ padding: 0
+ text: itemDelegateText.text
+
+ contentItem: Text {
+ id: itemDelegateText
+ leftPadding: 8
+ text: modelData
+ color: StudioTheme.Values.themeTextColor
+ font: textField.font
+ elide: Text.ElideRight
+ verticalAlignment: Text.AlignVCenter
+ }
+ background: Rectangle {
+ color: "transparent"
+ }
+
+ hoverEnabled: true
+ onHoveredChanged: {
+ if (hovered)
+ listView.currentIndex = index
+ }
+ onClicked: {
+ listView.currentIndex = index
+ if (textField.completionActive)
+ textField.commitCompletion()
+ }
}
- ]
+ highlight: Rectangle {
+ id: listViewHighlight
+ width: textFieldPopup.width - textFieldPopup.leftPadding - textFieldPopup.rightPadding
+ - (popupScrollBar.visible ? popupScrollBar.contentItem.implicitWidth
+ + 2 : 0)
+ height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
+ color: StudioTheme.Values.themeInteraction
+ y: listView.currentItem.y
+ }
+ highlightFollowsCurrentItem: false
+ }
+
+ background: Rectangle {
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeInteraction
+ border.width: StudioTheme.Values.border
+ }
+
+ enter: Transition {
+ }
+ exit: Transition {
+ }
}
verticalAlignment: Text.AlignTop
+ onPressed: listView.model = null
+
Keys.priority: Keys.BeforeItem
Keys.onPressed: {
+ var text = textField.text
+ var pos = textField.cursorPosition
+ var explicitComplete = true
+
+ switch (event.key) {
- if (event.key === Qt.Key_Period) {
+ case Qt.Key_Period:
textField.dotCursorPos = textField.cursorPosition + 1
- var list = autoComplete(textField.text+".", textField.dotCursorPos, false, textField.completeOnlyTypes)
- textField.prefix = list.pop()
- listView.model = list;
+ text = textField.text + "."
+ pos = textField.dotCursorPos
+ explicitComplete = false
textField.dotCompletion = true
- } else {
- if (textField.completionActive) {
- var list2 = autoComplete(textField.text + event.text,
- textField.cursorPosition + event.text.length,
- true, textField.completeOnlyTypes)
- textField.prefix = list2.pop()
- listView.model = list2;
- }
+ break
+
+ case Qt.Key_Right:
+ if (!textField.completionActive)
+ return
+
+ pos = Math.min(textField.cursorPosition + 1, textField.text.length)
+ break
+
+ case Qt.Key_Left:
+ if (!textField.completionActive)
+ return
+
+ pos = Math.max(0, textField.cursorPosition - 1)
+ break
+
+ case Qt.Key_Backspace:
+ if (!textField.completionActive)
+ return
+
+ pos = textField.cursorPosition - 1
+ if (pos < 0)
+ return
+
+ text = textField.text.substring(0, pos) + textField.text.substring(textField.cursorPosition)
+ break
+
+ case Qt.Key_Delete:
+ return
+
+ default:
+ if (!textField.completionActive)
+ return
+
+ var tmp = textField.text
+ text = tmp.substring(0, textField.cursorPosition) + event.text + tmp.substring(textField.cursorPosition)
+ pos = textField.cursorPosition + event.text.length
}
+
+ var list = autoComplete(text.trim(), pos, explicitComplete, textField.completeOnlyTypes)
+ textField.prefix = text.substring(0, pos)
+
+ if (list.length && list[list.length - 1] === textField.prefix)
+ list.pop()
+
+ listView.model = list
}
Keys.onSpacePressed: {
if (event.modifiers & Qt.ControlModifier) {
var list = autoComplete(textField.text, textField.cursorPosition, true, textField.completeOnlyTypes)
- textField.prefix = list.pop()
- listView.model = list;
+ textField.prefix = textField.text.substring(0, textField.cursorPosition)
+ if (list.length && list[list.length - 1] === textField.prefix)
+ list.pop()
+
+ listView.model = list
textField.dotCompletion = false
event.accepted = true;
-
- if (list.length === 1)
- textField.commitCompletion()
-
} else {
event.accepted = false
}