QmlDesigner: Improve design system view

* Add custom SpinBox with input and indicator
* Set value on SpinBox destruction when value was changed
* Add binding indicator
* Implement binding menu and connect it to the backend
* Add readonly state to custom Switch
* Update StudioControls.DialogButton style
* Add dialogs for creating, deleting and renaming collections
* Fix crash in CollectionModel::setData
* Add themes/mode ComboBox
* Fix color editor connection
* Add overlay for header view editing

Task-number: QDS-11856
Change-Id: Ibc5fdd915a298162ed4970fb2845d7484a8f042a
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
(cherry picked from commit 30c62e3a32)
This commit is contained in:
Henning Gruendl
2025-01-31 16:57:10 +01:00
committed by Henning Gründl
parent 04f1512194
commit 2bfdd6856a
11 changed files with 1604 additions and 170 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Templates as T
import StudioTheme as StudioTheme
Item {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property alias icon: icon
property bool hover: mouseArea.containsMouse//false
property bool pressed: false
property bool forceVisible: false
implicitWidth: control.style.actionIndicatorSize.width
implicitHeight: control.style.actionIndicatorSize.height
signal clicked
z: 10
T.Label {
id: icon
anchors.fill: parent
text: StudioTheme.Constants.actionIcon
color: control.style.icon.idle
font.family: StudioTheme.Constants.iconFont.family
font.pixelSize: control.style.baseIconFontSize
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
states: [
State {
name: "hover"
when: control.hover && !control.pressed && control.enabled
PropertyChanges {
target: icon
scale: 1.2
visible: true
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: icon
color: control.style.icon.disabled
}
}
]
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
//onContainsMouseChanged: control.hover = mouseArea.containsMouse
onClicked: control.clicked()
}
}

View File

@@ -0,0 +1,365 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Templates as T
import StudioTheme as StudioTheme
import StudioQuickUtils
T.SpinBox {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property real realFrom: 0.0
property real realTo: 99.0
property real realValue: 1.0
property real realStepSize: 1.0
property alias labelColor: spinBoxInput.color
property int decimals: 0
property real minStepSize: {
var tmpMinStepSize = Number((control.realStepSize * 0.1).toFixed(control.decimals))
return (tmpMinStepSize) ? tmpMinStepSize : control.realStepSize
}
property real maxStepSize: {
var tmpMaxStepSize = Number((control.realStepSize * 10.0).toFixed(control.decimals))
return (tmpMaxStepSize < control.realTo) ? tmpMaxStepSize : control.realStepSize
}
property bool edit: spinBoxInput.activeFocus
// This property is used to indicate the global hover state
property bool hover: (spinBoxInput.hover || spinBoxIndicatorUp.hover || spinBoxIndicatorDown.hover)
&& control.enabled
property bool dirty: false // user modification flag
property bool spinBoxIndicatorVisible: true
property real __spinBoxIndicatorWidth: control.style.spinBoxIndicatorSize.width
property real __spinBoxIndicatorHeight: control.height / 2 - control.style.borderWidth
property alias compressedValueTimer: myTimer
property string preFocusText: ""
signal realValueModified
signal compressedRealValueModified
signal indicatorPressed
locale: Utils.locale
// Use custom wheel handling due to bugs
property bool __wheelEnabled: false
wheelEnabled: false
hoverEnabled: true
width: control.style.controlSize.width
height: control.style.controlSize.height
leftPadding: spinBoxIndicatorDown.x + spinBoxIndicatorDown.width
rightPadding: control.style.borderWidth
font.pixelSize: control.style.baseFontSize
editable: true
// Leave this in for now
from: -99
value: 0
to: 99
function checkAndClearFocus() {
if (!spinBoxIndicatorUp.activeFocus && !spinBoxIndicatorDown.activeFocus && !spinBoxInput.activeFocus)
control.focus = false
}
DoubleValidator {
id: doubleValidator
locale: control.locale
notation: DoubleValidator.StandardNotation
decimals: control.decimals
bottom: Math.min(control.realFrom, control.realTo)
top: Math.max(control.realFrom, control.realTo)
}
IntValidator {
id: intValidator
locale: control.locale
bottom: Math.round(Math.min(control.realFrom, control.realTo))
top: Math.round(Math.max(control.realFrom, control.realTo))
}
validator: control.decimals === 0 ? intValidator : doubleValidator
up.indicator: SpinBoxIndicator {
id: spinBoxIndicatorUp
style: control.style
parentHover: control.hover
parentEdit: control.edit
iconFlip: -1
visible: control.spinBoxIndicatorVisible
onRealPressed: control.indicatorPressed()
onRealReleased: control.realIncrease()
onRealPressAndHold: control.realIncrease()
x: control.style.borderWidth
y: control.style.borderWidth
width: control.spinBoxIndicatorVisible ? control.__spinBoxIndicatorWidth : 0
height: control.spinBoxIndicatorVisible ? control.__spinBoxIndicatorHeight : 0
realEnabled: (control.realFrom < control.realTo) ? (control.realValue < control.realTo)
: (control.realValue > control.realTo)
}
down.indicator: SpinBoxIndicator {
id: spinBoxIndicatorDown
style: control.style
parentHover: control.hover
parentEdit: control.edit
visible: control.spinBoxIndicatorVisible
onRealPressed: control.indicatorPressed()
onRealReleased: control.realDecrease()
onRealPressAndHold: control.realDecrease()
x: control.style.borderWidth
y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height
width: control.spinBoxIndicatorVisible ? control.__spinBoxIndicatorWidth : 0
height: control.spinBoxIndicatorVisible ? control.__spinBoxIndicatorHeight : 0
realEnabled: (control.realFrom < control.realTo) ? (control.realValue > control.realFrom)
: (control.realValue < control.realFrom)
}
contentItem: SpinBoxInput {
id: spinBoxInput
style: control.style
validator: control.validator
font: control.font
readOnly: !control.editable
inputMethodHints: control.inputMethodHints
function handleEditingFinished() {
control.checkAndClearFocus()
// Keep the dirty state before calling setValueFromInput(),
// it will be set to false (cleared) internally
var valueModified = control.dirty
control.setValueFromInput()
myTimer.stop()
// Only trigger the signal, if the value was modified
if (valueModified)
control.compressedRealValueModified()
}
onEditingFinished: {
spinBoxInput.focus = false
spinBoxInput.handleEditingFinished()
}
onTextEdited: control.dirty = true
}
background: Rectangle {
id: spinBoxBackground
color: control.style.background.idle
border.color: control.style.border.idle
border.width: control.style.borderWidth
x: 0
width: control.width
height: control.height
}
textFromValue: function (value, locale) {
// -128 is the value of QLocale::FloatingPointShortest
return Number(control.realValue).toLocaleString(locale, 'f', -128)
}
valueFromText: function (text, locale) {
control.setRealValue(Number.fromLocaleString(locale, spinBoxInput.text))
return 0
}
states: [
State {
name: "default"
when: control.enabled && !control.hover && !control.hovered
&& !control.edit
PropertyChanges {
target: control
__wheelEnabled: false
}
PropertyChanges {
target: spinBoxInput
selectByMouse: false
}
PropertyChanges {
target: spinBoxBackground
color: control.style.background.idle
border.color: control.style.border.idle
}
},
State {
name: "hover"
when: control.enabled && control.hover && control.hovered
&& !control.edit
PropertyChanges {
target: spinBoxBackground
border.color: control.style.border.hover
}
},
State {
name: "edit"
when: control.edit
PropertyChanges {
target: control
__wheelEnabled: true
}
PropertyChanges {
target: spinBoxInput
selectByMouse: true
}
PropertyChanges {
target: spinBoxBackground
border.color: control.style.border.interaction
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: spinBoxBackground
border.color: control.style.border.disabled
}
}
]
Timer {
id: myTimer
repeat: false
running: false
interval: 400
onTriggered: control.compressedRealValueModified()
}
onRealValueChanged: {
control.setRealValue(control.realValue) // sanitize and clamp realValue
spinBoxInput.text = control.textFromValue(control.realValue, control.locale)
control.value = 0 // Without setting value back to 0, it can happen that one of
// the indicator will be disabled due to range logic.
}
onRealValueModified: myTimer.restart()
onFocusChanged: {
if (control.focus)
control.dirty = false
}
onDisplayTextChanged: spinBoxInput.text = control.displayText
onActiveFocusChanged: {
if (control.activeFocus) { // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
control.preFocusText = spinBoxInput.text
spinBoxInput.selectAll()
} else {
// Make sure displayed value is correct after focus loss, as onEditingFinished
// doesn't trigger when value is something validator doesn't accept.
if (spinBoxInput.text === "")
spinBoxInput.text = control.textFromValue(control.realValue, control.locale)
if (control.dirty)
spinBoxInput.handleEditingFinished()
}
}
onDecimalsChanged: spinBoxInput.text = control.textFromValue(control.realValue, control.locale)
Keys.onPressed: function(event) {
if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
event.accepted = true
// Store current step size
var currStepSize = control.realStepSize
// Set realStepSize according to used modifier key
if (event.modifiers & Qt.ControlModifier)
control.realStepSize = control.minStepSize
if (event.modifiers & Qt.ShiftModifier)
control.realStepSize = control.maxStepSize
if (event.key === Qt.Key_Up)
control.realIncrease()
else
control.realDecrease()
// Reset realStepSize
control.realStepSize = currStepSize
}
if (event.key === Qt.Key_Escape) {
spinBoxInput.text = control.preFocusText
control.dirty = true
spinBoxInput.handleEditingFinished()
}
}
function clamp(v, lo, hi) {
return (v < lo || v > hi) ? Math.min(Math.max(lo, v), hi) : v
}
function setValueFromInput() {
if (!control.dirty)
return
// FIX: This is a temporary fix for QTBUG-74239
var currValue = control.realValue
// Call the function but don't use return value. The realValue property
// will be implicitly set inside the function/procedure.
control.valueFromText(spinBoxInput.text, control.locale)
if (control.realValue !== currValue) {
control.realValueModified()
} else {
// Check if input text differs in format from the current value
var tmpInputValue = control.textFromValue(control.realValue, control.locale)
if (tmpInputValue !== spinBoxInput.text)
spinBoxInput.text = tmpInputValue
}
control.dirty = false
}
function setRealValue(value) {
if (Number.isNaN(value))
value = 0
if (control.decimals === 0)
value = Math.round(value)
control.realValue = control.clamp(value,
control.validator.bottom,
control.validator.top)
}
function realDecrease() {
// Store the current value for comparison
var currValue = control.realValue
control.valueFromText(spinBoxInput.text, control.locale)
control.setRealValue(control.realValue - control.realStepSize)
if (control.realValue !== currValue)
control.realValueModified()
}
function realIncrease() {
// Store the current value for comparison
var currValue = control.realValue
control.valueFromText(spinBoxInput.text, control.locale)
control.setRealValue(control.realValue + control.realStepSize)
if (control.realValue !== currValue)
control.realValueModified()
}
}

View File

@@ -0,0 +1,247 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Templates as T
import StudioTheme as StudioTheme
Rectangle {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property bool hover: spinBoxIndicatorMouseArea.containsMouse
property bool pressed: spinBoxIndicatorMouseArea.containsPress
property bool released: false
property bool realEnabled: true
property bool parentHover: false
property bool parentEdit: false
signal realPressed
signal realPressAndHold
signal realReleased
property alias iconFlip: spinBoxIndicatorIconScale.yScale
color: control.style.background.idle
border.width: 0
onEnabledChanged: control.syncEnabled()
onRealEnabledChanged: {
control.syncEnabled()
if (control.realEnabled === false) {
pressAndHoldTimer.stop()
spinBoxIndicatorMouseArea.pressedAndHeld = false
}
}
// This function is meant to synchronize enabled with realEnabled to avoid
// the internal logic messing with the actual state.
function syncEnabled() {
control.enabled = control.realEnabled
}
Timer {
id: pressAndHoldTimer
repeat: true
running: false
interval: 100
onTriggered: control.realPressAndHold()
}
// This MouseArea is a workaround to avoid some hover state related bugs
// when using the actual signal 'up.hovered'. QTBUG-74688
MouseArea {
id: spinBoxIndicatorMouseArea
property bool pressedAndHeld: false
anchors.fill: parent
hoverEnabled: true
pressAndHoldInterval: 500
onPressed: function(mouse) {
//if (control.__parentControl.activeFocus)
// control.forceActiveFocus()
control.realPressed()
mouse.accepted = true
}
onPressAndHold: {
pressAndHoldTimer.restart()
spinBoxIndicatorMouseArea.pressedAndHeld = true
}
onReleased: function(mouse) {
// Only trigger real released when pressAndHold isn't active
if (!pressAndHoldTimer.running && containsMouse)
control.realReleased()
pressAndHoldTimer.stop()
mouse.accepted = true
spinBoxIndicatorMouseArea.pressedAndHeld = false
}
onEntered: {
if (spinBoxIndicatorMouseArea.pressedAndHeld)
pressAndHoldTimer.restart()
}
onExited: {
if (pressAndHoldTimer.running)
pressAndHoldTimer.stop()
}
}
T.Label {
id: spinBoxIndicatorIcon
text: StudioTheme.Constants.upDownSquare2
color: control.style.icon.idle
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: control.style.smallIconFontSize
font.family: StudioTheme.Constants.iconFont.family
anchors.fill: parent
transform: Scale {
id: spinBoxIndicatorIconScale
origin.x: 0
origin.y: spinBoxIndicatorIcon.height / 2
yScale: 1
}
states: [
State {
name: "default"
when: control.enabled && !control.hover && !control.parentEdit && !control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.idle
}
},
State {
name: "globalHover"
when: control.enabled && !control.hover && !control.parentEdit && control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.idle
}
},
State {
name: "hover"
when: control.enabled && control.hover && !control.pressed && control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.hover
}
},
State {
name: "press"
when: control.enabled && control.pressed
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.idle
}
},
State {
name: "parentEdit"
when: control.parentEdit && control.enabled
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.idle
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: spinBoxIndicatorIcon
color: control.style.icon.disabled
}
}
]
}
states: [
State {
name: "default"
when: !control.parentEdit && !control.hover && !control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
visible: false
}
PropertyChanges {
target: control
color: control.style.background.idle
}
},
State {
name: "globalHover"
when: control.enabled && !control.hover && !control.parentEdit && control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
visible: true
}
PropertyChanges {
target: control
color: control.style.background.globalHover
}
},
State {
name: "hover"
when: control.enabled && control.hover && !control.pressed && control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
visible: true
}
PropertyChanges {
target: control
color: control.style.background.hover
}
},
State {
name: "press"
when: control.enabled && control.pressed
PropertyChanges {
target: spinBoxIndicatorIcon
visible: true
}
PropertyChanges {
target: control
color: control.style.interaction
}
},
State {
name: "parentEdit"
when: control.parentEdit && control.enabled
PropertyChanges {
target: spinBoxIndicatorIcon
visible: true
}
PropertyChanges {
target: control
color: control.style.background.idle
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: spinBoxIndicatorIcon
visible: false
}
PropertyChanges {
target: control
color: control.style.background.disabled
}
},
State {
name: "limit"
when: !control.enabled && !control.realEnabled && control.parentHover
PropertyChanges {
target: spinBoxIndicatorIcon
visible: true
}
PropertyChanges {
target: control
color: control.style.background.idle
}
}
]
}

View File

@@ -0,0 +1,100 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Templates as T
import StudioTheme as StudioTheme
TextInput {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property bool edit: control.activeFocus
property bool drag: false
property bool hover: hoverHandler.hovered && control.enabled
z: 2
color: control.style.text.idle
selectionColor: control.style.text.selection
selectedTextColor: control.style.text.selectedText
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
leftPadding: control.style.inputHorizontalPadding
rightPadding: control.style.inputHorizontalPadding
selectByMouse: false
activeFocusOnPress: false
clip: true
// TextInput focus needs to be set to activeFocus whenever it changes,
// otherwise TextInput will get activeFocus whenever the parent SpinBox gets
// activeFocus. This will lead to weird side effects.
onActiveFocusChanged: control.focus = control.activeFocus
HoverHandler { id: hoverHandler }
Rectangle {
id: textInputBackground
x: 0
y: control.style.borderWidth
z: -1
width: control.width
height: control.height - (control.style.borderWidth * 2)
color: control.style.background.idle
border.width: 0
}
// Ensure that we get Up and Down key press events first
Keys.onShortcutOverride: function(event) {
event.accepted = (event.key === Qt.Key_Up || event.key === Qt.Key_Down)
}
states: [
State {
name: "default"
when: control.enabled && !control.edit && !control.hover
PropertyChanges {
target: textInputBackground
color: control.style.background.idle
}
},
State {
name: "globalHover"
when: !control.hover && !control.edit
PropertyChanges {
target: textInputBackground
color: control.style.background.globalHover
}
},
State {
name: "hover"
when: control.hover && !control.edit
PropertyChanges {
target: textInputBackground
color: control.style.background.hover
}
},
State {
name: "edit"
when: control.edit
PropertyChanges {
target: textInputBackground
color: control.style.background.interaction
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: textInputBackground
color: control.style.background.disabled
}
PropertyChanges {
target: control
color: control.style.text.disabled
}
}
]
}

View File

@@ -4,7 +4,7 @@
import QtQuick
import QtQuick.Templates as T
import StudioTheme 1.0 as StudioTheme
import StudioTheme as StudioTheme
T.Switch {
id: control
@@ -14,6 +14,7 @@ T.Switch {
// This property is used to indicate the global hover state
property bool hover: control.hovered && control.enabled
property bool edit: false
property bool readonly: false
property alias labelVisible: label.visible
property alias labelColor: label.color
@@ -33,6 +34,8 @@ T.Switch {
hoverEnabled: true
activeFocusOnTab: false
enabled: !control.readonly
indicator: Rectangle {
id: switchBackground
x: 0
@@ -60,6 +63,7 @@ T.Switch {
color: control.style.icon.idle
border.width: 0
}
}
contentItem: T.Label {
@@ -133,7 +137,7 @@ T.Switch {
},
State {
name: "disable"
when: !control.enabled && !control.checked
when: !control.enabled && !control.checked && !control.readonly
PropertyChanges {
target: switchBackground
color: control.style.background.disabled
@@ -186,8 +190,19 @@ T.Switch {
},
State {
name: "disableChecked"
when: !control.enabled && control.checked
when: !control.enabled && control.checked && !control.readonly
extend: "disable"
},
State {
name: "readonly"
when: !control.enabled && !control.checked && control.readonly
extend: "default"
},
State {
name: "readonlyChecked"
when: !control.enabled && control.checked && control.readonly
extend: "defaultChecked"
}
]
}

View File

@@ -1,3 +1,7 @@
BindingIndicator 1.0 BindingIndicator.qml
MenuItem 1.0 MenuItem.qml
SpinBox 1.0 SpinBox.qml
SpinBoxIndicator 1.0 SpinBoxIndicator.qml
SpinBoxInput 1.0 SpinBoxInput.qml
Switch 1.0 Switch.qml
TextField 1.0 TextField.qml

View File

@@ -3,27 +3,29 @@
import QtQuick
import QtQuick.Templates as T
import StudioTheme 1.0 as StudioTheme
import StudioTheme as StudioTheme
T.Button {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
implicitWidth: Math.max(buttonBackground ? buttonBackground.implicitWidth : 0,
textItem.implicitWidth + leftPadding + rightPadding)
implicitHeight: Math.max(buttonBackground ? buttonBackground.implicitHeight : 0,
textItem.implicitHeight + topPadding + bottomPadding)
implicitWidth: Math.max(control.style.squareControlSize.width,
implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(control.style.squareControlSize.height,
implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
leftPadding: control.style.dialogPadding
rightPadding: control.style.dialogPadding
background: Rectangle {
id: buttonBackground
implicitWidth: 70
implicitHeight: 20
id: controlBackground
color: control.style.background.idle
border.color: control.style.border.idle
anchors.fill: parent
border.width: control.style.borderWidth
radius: control.style.radius
}
contentItem: Text {
@@ -41,7 +43,7 @@ T.Button {
when: control.enabled && !control.down && !control.hovered && !control.checked
PropertyChanges {
target: buttonBackground
target: controlBackground
color: control.highlighted ? control.style.interaction
: control.style.background.idle
border.color: control.style.border.idle
@@ -56,7 +58,7 @@ T.Button {
when: control.enabled && control.hovered && !control.checked && !control.down
PropertyChanges {
target: buttonBackground
target: controlBackground
color: control.style.background.hover
border.color: control.style.border.hover
}
@@ -70,9 +72,9 @@ T.Button {
when: control.enabled && (control.checked || control.down)
PropertyChanges {
target: buttonBackground
color: control.style.background.interaction
border.color: control.style.border.interaction
target: controlBackground
color: control.style.interaction
border.color: control.style.interaction
}
PropertyChanges {
target: textItem
@@ -83,7 +85,7 @@ T.Button {
name: "disable"
when: !control.enabled
PropertyChanges {
target: buttonBackground
target: controlBackground
color: control.style.background.disabled
border.color: control.style.border.disabled
}

View File

@@ -116,6 +116,11 @@ QVariant CollectionModel::headerData(int section, Qt::Orientation orientation, i
Qt::ItemFlags CollectionModel::flags(const QModelIndex &index) const
{
// If group type is FLAGS and not binding block editable
if (data(index, Roles::GroupRole).value<GroupType>() == GroupType::Flags
&& !data(index, Roles::BindingRole).toBool())
return QAbstractItemModel::flags(index);
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
}
@@ -214,9 +219,9 @@ bool CollectionModel::setData(const QModelIndex &index, const QVariant &value, i
p.name = propName;
const ThemeId id = m_themeIdList[index.column()];
if (m_collection->updateProperty(id, groupType, p)) {
beginResetModel();
updateCache();
endResetModel();
emit dataChanged(index, index);
}
}
default:

View File

@@ -25,6 +25,7 @@ public:
ResolvedValueRole,
PropertyValueRole
};
Q_ENUM(Roles)
Q_PROPERTY(QStringList themeNames READ themeNameList NOTIFY themeNameChanged FINAL)

View File

@@ -14,6 +14,7 @@ DesignSystemInterface::DesignSystemInterface(DSStore *store)
{
qmlRegisterUncreatableMetaObject(
QmlDesigner::staticMetaObject, "QmlDesigner.DesignSystem", 1, 0, "GroupType", "");
qmlRegisterUncreatableType<CollectionModel>("QmlDesigner.DesignSystem", 1, 0, "CollectionModel", "");
}
DesignSystemInterface::~DesignSystemInterface() {}