forked from qt-creator/qt-creator
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:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
@@ -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()
|
||||
}
|
||||
|
Reference in New Issue
Block a user