QmlDesigner: Close the color editor popup before adding

Fixes: QDS-12498
Change-Id: Id3c565ffb9fca7f186ebeb0cf8051194c7944d4d
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
Ali Kianian
2024-05-15 16:48:28 +03:00
parent 92120273b1
commit 51a27f3a12
2 changed files with 173 additions and 238 deletions

View File

@@ -90,7 +90,7 @@ Rectangle {
property int order: Qt.AscendingOrder
onClicked: {
order = (order == Qt.AscendingOrder) ? Qt.DescendingOrder : Qt.AscendingOrder;
tableView.closeEditor()
tableView.closeEditors()
tableView.model.sort(-1, order)
}
}
@@ -173,7 +173,7 @@ Rectangle {
StudioControls.MenuItem {
text: qsTr("Sort Ascending")
onTriggered: {
tableView.closeEditor()
tableView.closeEditors()
tableView.model.sort(headerMenu.clickedHeaderIndex, Qt.AscendingOrder)
}
}
@@ -181,7 +181,7 @@ Rectangle {
StudioControls.MenuItem {
text: qsTr("Sort Descending")
onTriggered: {
tableView.closeEditor()
tableView.closeEditors()
tableView.model.sort(headerMenu.clickedHeaderIndex, Qt.DescendingOrder)
}
}
@@ -235,6 +235,8 @@ Rectangle {
property int targetRow
property int targetColumn
property Item popupEditingItem
Layout.alignment: Qt.AlignTop + Qt.AlignLeft
Layout.preferredWidth: tableView.contentWidth
Layout.preferredHeight: tableView.contentHeight
@@ -261,6 +263,24 @@ Rectangle {
return Math.max(h, StudioTheme.Values.collectionCellMinimumHeight)
}
function closePopupEditor() {
if (tableView.popupEditingItem)
tableView.popupEditingItem.closeEditor()
tableView.popupEditingItem = null
}
function openNewPopupEditor(item, editor) {
if (tableView.popupEditingItem !== item) {
closePopupEditor()
tableView.popupEditingItem = item
}
}
function closeEditors() {
closeEditor()
closePopupEditor()
}
function ensureRowIsVisible(row) {
let rows = tableView.model.rowCount()
let rowIsLoaded = tableView.isRowLoaded(row)
@@ -381,7 +401,36 @@ Rectangle {
Component {
id: colorEditorComponent
ColorViewDelegate {}
ColorViewDelegate {
id: colorEditorItem
readonly property color editValue: edit
readonly property color displayValue: display
property string _frontColorStr
property string _backendColorStr
actionIndicatorVisible: false
onColorChanged: {
_frontColorStr = colorEditorItem.color.toString()
if (_frontColorStr != _backendColorStr)
edit = colorEditorItem.color
}
Component.onCompleted: {
colorEditorItem.color = display
}
onDisplayValueChanged: {
_backendColorStr = colorEditorItem.displayValue.toString()
if (_frontColorStr != _backendColorStr)
colorEditorItem.color = colorEditorItem.displayValue
}
onEditorOpened: (item, editor) => {
tableView.openNewPopupEditor(item, editor)
}
}
}
function resetSource() {
@@ -441,13 +490,13 @@ Rectangle {
}
function onRowsInserted(parent, first, last) {
tableView.closeEditor()
tableView.closeEditors()
tableView.model.selectRow(first)
tableView.ensureRowIsVisible(first)
}
function onColumnsInserted(parent, first, last) {
tableView.closeEditor()
tableView.closeEditors()
tableView.model.selectColumn(first)
tableView.ensureColumnIsVisible(first)
}
@@ -503,7 +552,7 @@ Rectangle {
tooltip: "Add Column"
onClicked: {
tableView.closeEditor()
tableView.closeEditors()
toolbar.addNewColumn()
}
}
@@ -521,7 +570,7 @@ Rectangle {
tooltip: "Add Row"
onClicked: {
tableView.closeEditor()
tableView.closeEditors()
toolbar.addNewRow()
}
}

View File

@@ -10,170 +10,59 @@ import StudioTheme as StudioTheme
import StudioControls as StudioControls
import QtQuickDesignerTheme
import QtQuickDesignerColorPalette
import StudioHelpers
Row {
id: colorEditor
Item {
id: root
property color color
property bool supportGradient: false
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property QtObject backendValue: QtObject {
property color value: edit
readonly property color editColor: edit
property alias color: colorBackend.color
function resetValue() {
if (value)
value = ""
property alias actionIndicatorVisible: actionIndicator.visible
property real __actionIndicatorWidth: root.style.actionIndicatorSize.width
property real __actionIndicatorHeight: root.style.actionIndicatorSize.height
property alias showHexTextField: hexTextField.visible
readonly property real padding: 2
readonly property real innerItemsHeight: root.height - 2 * root.padding
width: root.style.controlSize.width
height: root.style.controlSize.height
clip: true
signal editorOpened(var item, var editorPopup)
function closeEditor() {
loader.close()
}
onValueChanged: {
if (editColor !== value)
edit = value
}
ColorBackend {
id: colorBackend
}
property variant value: {
if (!colorEditor.backendValue || !colorEditor.backendValue.value)
return "white" // default color for Rectangle
if (colorEditor.isVector3D) {
return Qt.rgba(colorEditor.backendValue.value.x,
colorEditor.backendValue.value.y,
colorEditor.backendValue.value.z, 1)
}
return colorEditor.backendValue.value
}
property alias gradientPropertyName: popupDialog.gradientPropertyName
property alias gradientThumbnail: gradientThumbnail
property alias shapeGradientThumbnail: shapeGradientThumbnail
property bool shapeGradients: false
property bool isVector3D: false
property color originalColor
property bool __block: false
function resetShapeColor() {
colorEditor.backendValue.resetValue()
}
function writeColor() {
if (colorEditor.isVector3D) {
colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r,
colorEditor.color.g,
colorEditor.color.b)
} else {
colorEditor.backendValue.value = colorEditor.color
}
}
function initEditor() {
colorEditor.syncColor()
}
// Syncing color from backend to frontend and block reflection
function syncColor() {
colorEditor.__block = true
colorEditor.color = colorEditor.value
hexTextField.syncColor()
colorEditor.__block = false
}
Connections {
id: backendConnection
target: colorEditor
function onValueChanged() {
if (popupDialog.isSolid())
colorEditor.syncColor()
}
function onBackendValueChanged() {
if (popupDialog.isSolid())
colorEditor.syncColor()
}
}
Timer {
id: colorEditorTimer
repeat: false
interval: 100
running: false
onTriggered: {
backendConnection.enabled = false
colorEditor.writeColor()
hexTextField.syncColor()
backendConnection.enabled = true
}
}
onColorChanged: {
if (colorEditor.__block)
return
if (!popupDialog.isInValidState)
return
popupDialog.commitToGradient()
// Delay setting the color to keep ui responsive
if (popupDialog.isSolid())
colorEditorTimer.restart()
StudioControls.ActionIndicator {
id: actionIndicator
style: root.style
__parentControl: root
x: root.padding
y: root.padding
width: actionIndicator.visible ? root.__actionIndicatorWidth : 0
height: actionIndicator.visible ? root.__actionIndicatorHeight : 0
}
Rectangle {
id: preview
implicitWidth: StudioTheme.Values.twoControlColumnWidth
implicitHeight: StudioTheme.Values.height
color: colorEditor.color
border.color: StudioTheme.Values.themeControlOutline
border.width: StudioTheme.Values.border
Rectangle {
id: gradientThumbnail
anchors.fill: parent
anchors.margins: StudioTheme.Values.border
visible: !popupDialog.isSolid()
&& !colorEditor.shapeGradients
&& popupDialog.isLinearGradient()
}
Shape {
id: shape
anchors.fill: parent
anchors.margins: StudioTheme.Values.border
visible: !popupDialog.isSolid() && colorEditor.shapeGradients
ShapePath {
id: shapeGradientThumbnail
startX: shape.x - 1
startY: shape.y - 1
strokeWidth: -1
strokeColor: "green"
PathLine {
x: shape.x - 1
y: shape.height
}
PathLine {
x: shape.width
y: shape.height
}
PathLine {
x: shape.width
y: shape.y - 1
}
}
}
x: root.padding + actionIndicator.width
y: root.padding
z: previewMouseArea.containsMouse ? 10 : 0
implicitWidth: root.innerItemsHeight
implicitHeight: root.innerItemsHeight
color: root.color
border.color: previewMouseArea.containsMouse ? root.style.border.hover : root.style.border.idle
border.width: root.style.borderWidth
Image {
anchors.fill: parent
@@ -183,114 +72,111 @@ Row {
}
MouseArea {
id: previewMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
popupDialog.visibility ? popupDialog.close() : popupDialog.open()
forceActiveFocus()
loader.toggle()
previewMouseArea.forceActiveFocus()
}
}
StudioControls.PopupDialog {
id: popupDialog
property bool isInValidState: loader.active ? popupDialog.loaderItem.isInValidState : true
property QtObject loaderItem: loader.item
property string gradientPropertyName
keepOpen: loader.item?.eyeDropperActive ?? false
width: 260
function commitToGradient() {
if (!loader.active)
return
if (colorEditor.supportGradient && popupDialog.loaderItem.gradientModel.hasGradient) {
var hexColor = convertColorToString(colorEditor.color)
hexTextField.text = hexColor
colorEditor.backendValue.value = hexColor
popupDialog.loaderItem.commitGradientColor()
}
}
function isSolid() {
if (!loader.active)
return true
return popupDialog.loaderItem.isSolid()
}
function isLinearGradient(){
if (!loader.active)
return false
return popupDialog.loaderItem.isLinearGradient()
}
function ensureLoader() {
if (!loader.active)
loader.active = true
}
function open() {
popupDialog.ensureLoader()
popupDialog.loaderItem.initEditor()
popupDialog.show(preview)
}
function determineActiveColorMode() {
if (loader.active && popupDialog.loaderItem)
popupDialog.loaderItem.determineActiveColorMode()
else
colorEditor.syncColor()
}
Loader {
id: loader
active: colorEditor.supportGradient
function ensureLoader() {
if (!loader.active)
loader.active = true
if (loader.sourceComponent === null)
loader.sourceComponent = popupDialogComponent
}
sourceComponent: HelperWidgets.ColorEditorPopup {
shapeGradients: colorEditor.shapeGradients
supportGradient: colorEditor.supportGradient
function open() {
loader.ensureLoader()
loader.item.show(preview)
if (loader.status === Loader.Ready)
loader.item.originalColor = root.color
}
function close() {
if (loader.item)
loader.item.close()
}
function toggle() {
if (loader.item)
loader.close()
else
loader.open()
}
Component {
id: popupDialogComponent
StudioControls.PopupDialog {
id: popupDialog
property alias color: popup.color
property alias originalColor: popup.originalColor
titleBar: popup.titleBarContent
width: 260
StudioControls.ColorEditorPopup {
id: popup
width: popupDialog.contentWidth
onActivateColor: function(color) {
colorBackend.activateColor(color)
}
}
onClosing: {
loader.sourceComponent = null
}
}
}
sourceComponent: null
Binding {
target: loader.item
property: "color"
value: root.color
when: loader.status === Loader.Ready
}
onLoaded: {
popupDialog.loaderItem.initEditor()
popupDialog.titleBar = loader.item.titleBarContent
}
loader.item.originalColor = root.color
root.editorOpened(root, loader.item)
}
}
}
HelperWidgets.LineEdit {
StudioControls.TextField {
id: hexTextField
implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
width: hexTextField.implicitWidth
enabled: popupDialog.isSolid()
writeValueManually: true
style: root.style
x: root.padding + actionIndicator.width + preview.width - preview.border.width
y: root.padding
width: root.width - hexTextField.x - 2 * root.padding
height: root.innerItemsHeight
text: root.color
actionIndicatorVisible: false
translationIndicatorVisible: false
indicatorVisible: true
indicator.icon.text: StudioTheme.Constants.copy_small
indicator.onClicked: {
hexTextField.selectAll()
hexTextField.copy()
hexTextField.deselect()
}
validator: RegularExpressionValidator {
regularExpression: /#[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?/g
}
showTranslateCheckBox: false
showExtendedFunctionButton: false
indicatorVisible: false
onAccepted: colorEditor.color = hexTextField.text
onCommitData: {
colorEditor.color = hexTextField.text
if (popupDialog.isSolid())
colorEditor.writeColor()
onAccepted: colorBackend.activateColor(colorFromString(hexTextField.text))
}
function syncColor() {
hexTextField.text = colorEditor.color
}
}
Component.onCompleted: popupDialog.determineActiveColorMode()
onBackendValueChanged: popupDialog.determineActiveColorMode()
}