forked from qt-creator/qt-creator
QmlDesigner/StateEditor: Improve adding new states
- Added a big add button at the end of the states list. - Small add states button jumps in (bottom right) when the big button is out of the view. - View scrolls to the end when a new slide is added. Task-number: QDS-5973 Change-Id: Ida96bd663cc0caf32889638fbf4ac9f617916368 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -64,9 +64,6 @@ Rectangle {
|
||||
|
||||
color: isCurrentState ? StudioTheme.Values.themeInteraction
|
||||
: StudioTheme.Values.themeControlBackgroundInteraction
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin)
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
@@ -26,6 +26,7 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuickDesignerTheme 1.0
|
||||
import Qt.labs.qmlmodels 1.0
|
||||
import HelperWidgets 2.0
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
@@ -73,9 +74,16 @@ FocusScope {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 4 + scrollBarH
|
||||
width: 30
|
||||
height: 30
|
||||
anchors.bottomMargin: statesListView.contentWidth - statesListView.contentX - root.delegateWidth / 2 > statesListView.width ? scrollBarH + 5 : -35
|
||||
width: 35
|
||||
height: 35
|
||||
|
||||
Behavior on anchors.bottomMargin {
|
||||
PropertyAnimation {
|
||||
duration: 700
|
||||
easing.type: Easing.InOutBack
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: root.createNewState()
|
||||
}
|
||||
@@ -93,24 +101,81 @@ FocusScope {
|
||||
orientation: ListView.Horizontal
|
||||
spacing: root.innerSpacing
|
||||
|
||||
delegate: StatesDelegate {
|
||||
id: statesDelegate
|
||||
width: root.delegateWidth
|
||||
height: root.delegateHeight
|
||||
isBaseState: 0 === internalNodeId
|
||||
isCurrentState: root.currentStateInternalId === internalNodeId
|
||||
delegateStateName: stateName
|
||||
delegateStateImageSource: stateImageSource
|
||||
delegateHasWhenCondition: hasWhenCondition
|
||||
delegateWhenConditionString: whenConditionString
|
||||
|
||||
topAreaHeight: root.delegateTopAreaHeight
|
||||
bottomAreaHeight: root.delegateBottomAreaHeight
|
||||
stateMargin: root.delegateStateMargin
|
||||
previewMargin: root.delegatePreviewMargin
|
||||
scrollBarH: root.scrollBarH
|
||||
listMargin: root.listMargin
|
||||
property int prevCount: 0
|
||||
onCountChanged: {
|
||||
if (count > prevCount)
|
||||
Qt.callLater(statesListView.positionViewAtEnd)
|
||||
prevCount = count
|
||||
}
|
||||
|
||||
delegate: DelegateChooser {
|
||||
role: "type"
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: "state"
|
||||
|
||||
StatesDelegate {
|
||||
width: root.delegateWidth
|
||||
height: root.delegateHeight
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin)
|
||||
isBaseState: 0 === internalNodeId
|
||||
isCurrentState: root.currentStateInternalId === internalNodeId
|
||||
delegateStateName: stateName
|
||||
delegateStateImageSource: stateImageSource
|
||||
delegateHasWhenCondition: hasWhenCondition
|
||||
delegateWhenConditionString: whenConditionString
|
||||
|
||||
topAreaHeight: root.delegateTopAreaHeight
|
||||
bottomAreaHeight: root.delegateBottomAreaHeight
|
||||
stateMargin: root.delegateStateMargin
|
||||
previewMargin: root.delegatePreviewMargin
|
||||
scrollBarH: root.scrollBarH
|
||||
listMargin: root.listMargin
|
||||
}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: "add"
|
||||
|
||||
Rectangle {
|
||||
visible: canAddNewStates
|
||||
|
||||
width: root.delegateWidth
|
||||
height: root.delegateHeight
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin)
|
||||
color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
|
||||
|
||||
ToolTip.text: qsTr("Add a new state.")
|
||||
ToolTip.visible: addState.containsMouse
|
||||
ToolTip.delay: 1000
|
||||
|
||||
Rectangle { // inner rect
|
||||
width: parent.width - 30
|
||||
height: parent.height - 30
|
||||
anchors.centerIn: parent
|
||||
color: StudioTheme.Values.themeStateBackground
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "+"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -5
|
||||
font.pixelSize: parent.height * .5
|
||||
color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: addState
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: root.createNewState()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.horizontal: HorizontalScrollBar {}
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,6 @@ StatesEditorModel::StatesEditorModel(StatesEditorView *view)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int StatesEditorModel::count() const
|
||||
{
|
||||
return rowCount();
|
||||
@@ -64,9 +63,8 @@ QModelIndex StatesEditorModel::index(int row, int column, const QModelIndex &par
|
||||
if (m_statesEditorView.isNull())
|
||||
return {};
|
||||
|
||||
|
||||
int internalNodeId = 0;
|
||||
if (row > 0)
|
||||
if (row > 0 && row < rowCount() - 1) // first and last rows are base state, add state
|
||||
internalNodeId = m_statesEditorView->rootModelNode().nodeListProperty("states").at(row - 1).internalId();
|
||||
|
||||
return hasIndex(row, column, parent) ? createIndex(row, column, internalNodeId) : QModelIndex();
|
||||
@@ -78,9 +76,9 @@ int StatesEditorModel::rowCount(const QModelIndex &parent) const
|
||||
return 0;
|
||||
|
||||
if (!m_statesEditorView->rootModelNode().hasNodeListProperty("states"))
|
||||
return 1;
|
||||
return 2; // base state + add new state
|
||||
|
||||
return m_statesEditorView->rootModelNode().nodeListProperty("states").count() + 1;
|
||||
return m_statesEditorView->rootModelNode().nodeListProperty("states").count() + 2; // 2 = base state + add new state
|
||||
}
|
||||
|
||||
void StatesEditorModel::reset()
|
||||
@@ -101,16 +99,16 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
switch (role) {
|
||||
case StateNameRole: {
|
||||
if (index.row() == 0) {
|
||||
return tr("base state", "Implicit default state");
|
||||
} else {
|
||||
if (stateNode.hasVariantProperty("name"))
|
||||
return stateNode.variantProperty("name").value();
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (index.row() == 0) {
|
||||
return tr("base state", "Implicit default state");
|
||||
} else {
|
||||
if (stateNode.hasVariantProperty("name"))
|
||||
return stateNode.variantProperty("name").value();
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
case StateImageSourceRole: {
|
||||
static int randomNumber = 0;
|
||||
randomNumber++;
|
||||
@@ -119,9 +117,12 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
|
||||
else
|
||||
return QString("image://qmldesigner_stateseditor/%1-%2").arg(index.internalId()).arg(randomNumber);
|
||||
}
|
||||
case InternalNodeId: return index.internalId();
|
||||
|
||||
case HasWhenCondition: return stateNode.isValid() && stateNode.hasProperty("when");
|
||||
case InternalNodeId:
|
||||
return index.internalId();
|
||||
|
||||
case HasWhenCondition:
|
||||
return stateNode.isValid() && stateNode.hasProperty("when");
|
||||
|
||||
case WhenConditionString: {
|
||||
if (stateNode.isValid() && stateNode.hasBindingProperty("when"))
|
||||
@@ -137,10 +138,11 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
|
||||
return false;
|
||||
}
|
||||
|
||||
case ModelHasDefaultState: {
|
||||
case ModelHasDefaultState:
|
||||
return hasDefaultState();
|
||||
}
|
||||
|
||||
case StateType:
|
||||
return index.row() == rowCount() - 1 ? "add" : "state";
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -148,14 +150,15 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QHash<int, QByteArray> StatesEditorModel::roleNames() const
|
||||
{
|
||||
static QHash<int, QByteArray> roleNames{
|
||||
static QHash<int, QByteArray> roleNames {
|
||||
{StateNameRole, "stateName"},
|
||||
{StateImageSourceRole, "stateImageSource"},
|
||||
{InternalNodeId, "internalNodeId"},
|
||||
{HasWhenCondition, "hasWhenCondition"},
|
||||
{WhenConditionString, "whenConditionString"},
|
||||
{IsDefault, "isDefault"},
|
||||
{ModelHasDefaultState, "modelHasDefaultState"}
|
||||
{ModelHasDefaultState, "modelHasDefaultState"},
|
||||
{StateType, "type"}
|
||||
};
|
||||
return roleNames;
|
||||
}
|
||||
@@ -163,10 +166,8 @@ QHash<int, QByteArray> StatesEditorModel::roleNames() const
|
||||
void StatesEditorModel::insertState(int stateIndex)
|
||||
{
|
||||
if (stateIndex >= 0) {
|
||||
|
||||
const int updateIndex = stateIndex + 1;
|
||||
beginInsertRows(QModelIndex(), updateIndex, updateIndex);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
emit dataChanged(index(updateIndex, 0), index(updateIndex, 0));
|
||||
|
@@ -44,7 +44,8 @@ class StatesEditorModel : public QAbstractListModel
|
||||
HasWhenCondition,
|
||||
WhenConditionString,
|
||||
IsDefault,
|
||||
ModelHasDefaultState
|
||||
ModelHasDefaultState,
|
||||
StateType
|
||||
};
|
||||
|
||||
public:
|
||||
|
Reference in New Issue
Block a user