From 0d3ef2489d9f229c99f3dbcfc58e6029c60fb4a1 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 15 Dec 2021 11:56:24 +0200 Subject: QmlDesigner: Add some states view improvements - Added a gray border around unselected states. - States resize to fit view height. - States are centered vertically in the view. - Removed collapse option, auto collapse when space is small. - scroll bar always at the bottom. - Overshoot list ends. - Added margins around the states. - Add states button: make it small and docked to the bottom right. - Add states button doesnt take space from the view. Change-Id: I4fc96f4341a6e4a0c70509240b7aed9c7890ec4d Reviewed-by: Thomas Hartmann Reviewed-by: Miikka Heikkinen Reviewed-by: Samuel Ghinet Reviewed-by: --- .../statesEditorQmlSources/StatesDelegate.qml | 19 ++--- .../statesEditorQmlSources/StatesList.qml | 98 +++++++--------------- .../components/stateseditor/stateseditorview.cpp | 22 +++-- .../components/stateseditor/stateseditorview.h | 2 - .../components/stateseditor/stateseditorwidget.cpp | 21 +---- .../components/stateseditor/stateseditorwidget.h | 3 - .../qmldesigner/designercore/include/viewmanager.h | 2 - .../qmldesigner/designercore/model/viewmanager.cpp | 5 -- src/plugins/qmldesigner/designersettings.cpp | 1 - src/plugins/qmldesigner/designersettings.h | 1 - src/plugins/qmldesigner/shortcutmanager.cpp | 12 --- src/plugins/qmldesigner/shortcutmanager.h | 1 - 12 files changed, 54 insertions(+), 133 deletions(-) diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml index 08a7bc7dc3..a047735473 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml @@ -33,11 +33,8 @@ import StudioTheme 1.0 as StudioTheme Rectangle { id: myRoot - color: baseColor - property bool isBaseState property bool isCurrentState - property color baseColor property string delegateStateName property string delegateStateImageSource property bool delegateHasWhenCondition @@ -47,14 +44,14 @@ Rectangle { property int bottomAreaHeight property int stateMargin property int previewMargin - property int columnSpacing readonly property bool isDefaultState: isDefault property int closeButtonMargin: 6 property int textFieldMargin: 4 - signal delegateInteraction + property int scrollBarH: 0 + property int listMargin: 0 function autoComplete(text, pos, explicitComplete, filter) { var stringList = statesEditorModel.autoComplete(text, pos, explicitComplete) @@ -65,14 +62,19 @@ Rectangle { return statesEditorModel.hasAnnotation(internalNodeId) } + color: isCurrentState ? StudioTheme.Values.themeInteraction + : StudioTheme.Values.themeControlBackgroundInteraction + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin) + MouseArea { id: mouseArea anchors.fill: parent + onClicked: { focus = true root.currentStateInternalId = internalNodeId contextMenu.dismiss() // close potentially open context menu - myRoot.delegateInteraction() } } @@ -89,7 +91,6 @@ Rectangle { visible: !isBaseState && isCurrentState onClicked: { - myRoot.delegateInteraction() if (isDefaultState) statesEditorModel.resetDefaultState() @@ -254,9 +255,8 @@ Rectangle { Rectangle { // separator width: column.width - height: myRoot.columnSpacing + height: 2 color: StudioTheme.Values.themeStateSeparator - visible: expanded } Rectangle { @@ -264,7 +264,6 @@ Rectangle { width: myRoot.width - 2 * myRoot.stateMargin height: myRoot.bottomAreaHeight color: StudioTheme.Values.themeStateBackground - visible: expanded Image { anchors.fill: stateImageBackground diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml index 6f2dfbbf3d..718bbb746f 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml @@ -33,27 +33,24 @@ import StudioTheme 1.0 as StudioTheme FocusScope { id: root - property int delegateTopAreaHeight: StudioTheme.Values.height + 8 - property int delegateBottomAreaHeight: delegateHeight - 2 * delegateStateMargin - delegateTopAreaHeight - delegateColumnSpacing - property int delegateColumnSpacing: 2 - property int delegateStateMargin: 16 - property int delegatePreviewMargin: 10 - property int effectiveHeight: root.expanded ? Math.max(85, Math.min(287, root.height)) : 85 // height of the states area + readonly property int delegateTopAreaHeight: StudioTheme.Values.height + 8 + readonly property int delegateBottomAreaHeight: delegateHeight - 2 * delegateStateMargin - delegateTopAreaHeight - 2 + readonly property int delegateStateMargin: 16 + readonly property int delegatePreviewMargin: 10 + readonly property int effectiveHeight: root.height < 130 ? 89 : Math.min(root.height, 287) + + readonly property int scrollBarH: statesListView.ScrollBar.horizontal.scrollBarVisible ? StudioTheme.Values.scrollBarThickness : 0 + readonly property int listMargin: 10 + readonly property int delegateWidth: 264 + readonly property int delegateHeight: Math.max(effectiveHeight - scrollBarH - 2 * listMargin, 69) + readonly property int innerSpacing: 2 + + property int currentStateInternalId: 0 signal createNewState signal deleteState(int internalNodeId) signal duplicateCurrentState - property int padding: 2 - property int delegateWidth: 264 - property int delegateHeight: effectiveHeight - - StudioTheme.Values.scrollBarThickness - - 2 * (root.padding + StudioTheme.Values.border) - property int innerSpacing: 2 - property int currentStateInternalId: 0 - - property bool expanded: true - Connections { target: statesEditorModel function onChangedToState(n) { root.currentStateInternalId = n } @@ -65,69 +62,32 @@ FocusScope { color: StudioTheme.Values.themePanelBackground } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onClicked: function(mouse) { - if (mouse.button === Qt.LeftButton) { - contextMenu.dismiss() - focus = true - } else if (mouse.button === Qt.RightButton) { - contextMenu.popup() - } - } - - StudioControls.Menu { - id: contextMenu - - StudioControls.MenuItem { - text: root.expanded ? qsTr("Collapse") : qsTr("Expand") - onTriggered: root.expanded = !root.expanded - } - } - } - AbstractButton { id: addStateButton - buttonIcon: root.expanded ? qsTr("Create New State") : StudioTheme.Constants.plus - iconFont: root.expanded ? StudioTheme.Constants.font : StudioTheme.Constants.iconFont - iconSize: root.expanded ? StudioTheme.Values.myFontSize : StudioTheme.Values.myIconFontSize - iconItalic: root.expanded + buttonIcon: StudioTheme.Constants.plus + iconFont: StudioTheme.Constants.iconFont + iconSize: StudioTheme.Values.myIconFontSize tooltip: qsTr("Add a new state.") visible: canAddNewStates anchors.right: parent.right - anchors.rightMargin: 8 - y: (Math.min(effectiveHeight, root.height) - height) / 2 - width: root.expanded ? 140 : 18 - height: root.expanded ? 60 : 18 - - onClicked: { - contextMenu.dismiss() - root.createNewState() - } - } + anchors.rightMargin: 4 + anchors.bottom: parent.bottom + anchors.bottomMargin: 4 + scrollBarH + width: 30 + height: 30 - Rectangle { // separator lines between state items - color: StudioTheme.Values.themeStateSeparator - x: root.padding - y: root.padding - width: statesListView.width - height: root.delegateHeight + onClicked: root.createNewState() } ListView { id: statesListView - boundsBehavior: Flickable.StopAtBounds clip: true - - x: root.padding - y: root.padding - width: Math.min(root.delegateWidth * statesListView.count + root.innerSpacing * (statesListView.count - 1), - root.width - addStateButton.width - root.padding - 16) // 16 = 2 * 8 (addStateButton margin) - height: root.delegateHeight + StudioTheme.Values.scrollBarThickness + anchors.fill: parent + anchors.topMargin: listMargin + anchors.leftMargin: listMargin + anchors.rightMargin: listMargin model: statesEditorModel orientation: ListView.Horizontal @@ -139,20 +99,18 @@ FocusScope { height: root.delegateHeight isBaseState: 0 === internalNodeId isCurrentState: root.currentStateInternalId === internalNodeId - baseColor: isCurrentState ? StudioTheme.Values.themeInteraction : background.color delegateStateName: stateName delegateStateImageSource: stateImageSource delegateHasWhenCondition: hasWhenCondition delegateWhenConditionString: whenConditionString - onDelegateInteraction: contextMenu.dismiss() - columnSpacing: root.delegateColumnSpacing topAreaHeight: root.delegateTopAreaHeight bottomAreaHeight: root.delegateBottomAreaHeight stateMargin: root.delegateStateMargin previewMargin: root.delegatePreviewMargin + scrollBarH: root.scrollBarH + listMargin: root.listMargin } - ScrollBar.horizontal: HorizontalScrollBar {} } } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 997852cfb2..cf1f377141 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -85,12 +85,6 @@ void StatesEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorV checkForStatesAvailability(); } -void StatesEditorView::toggleStatesViewExpanded() -{ - if (m_statesEditorWidget) - m_statesEditorWidget->toggleStatesViewExpanded(); -} - void StatesEditorView::removeState(int nodeId) { try { @@ -102,6 +96,22 @@ void StatesEditorView::removeState(int nodeId) if (modelState.isValid()) { QStringList lockedTargets; const auto propertyChanges = modelState.propertyChanges(); + + // confirm removing not empty states + if (!propertyChanges.isEmpty()) { + QMessageBox msgBox; + msgBox.setTextFormat(Qt::RichText); + msgBox.setIcon(QMessageBox::Question); + msgBox.setWindowTitle(tr("Remove State")); + msgBox.setText(tr("This state is not empty. Are you sure you want to remove it?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Yes); + + if (msgBox.exec() == QMessageBox::Cancel) + return; + } + + // confirm removing states with locked targets for (const QmlPropertyChanges &change : propertyChanges) { const ModelNode target = change.target(); QTC_ASSERT(target.isValid(), continue); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index 1ac7a6f39f..71a82711ea 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -87,8 +87,6 @@ public: void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override; - void toggleStatesViewExpanded(); - public slots: void synchonizeCurrentStateFromWidget(); void createNewState(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index 4701a4079e..b7b391944a 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -133,13 +133,6 @@ QString StatesEditorWidget::qmlSourcesPath() return Core::ICore::resourcePath("qmldesigner/statesEditorQmlSources").toString(); } -void StatesEditorWidget::toggleStatesViewExpanded() -{ - QTC_ASSERT(rootObject(), return); - bool expanded = rootObject()->property("expanded").toBool(); - rootObject()->setProperty("expanded", !expanded); -} - void StatesEditorWidget::showEvent(QShowEvent *event) { QQuickWidget::showEvent(event); @@ -168,18 +161,6 @@ void StatesEditorWidget::reloadQmlSource() connect(rootObject(), SIGNAL(createNewState()), m_statesEditorView.data(), SLOT(createNewState())); connect(rootObject(), SIGNAL(deleteState(int)), m_statesEditorView.data(), SLOT(removeState(int))); m_statesEditorView.data()->synchonizeCurrentStateFromWidget(); - - if (!DesignerSettings::getValue(DesignerSettingsKey::STATESEDITOR_EXPANDED).toBool()) - toggleStatesViewExpanded(); - - connect(rootObject(), SIGNAL(expandedChanged()), this, SLOT(handleExpandedChanged())); } -void StatesEditorWidget::handleExpandedChanged() -{ - QTC_ASSERT(rootObject(), return); - - bool expanded = rootObject()->property("expanded").toBool(); - DesignerSettings::setValue(DesignerSettingsKey::STATESEDITOR_EXPANDED, expanded); -} -} +} // QmlDesigner diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h index e4e9668abb..b613e600c4 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h @@ -57,14 +57,11 @@ public: static QString qmlSourcesPath(); - void toggleStatesViewExpanded(); - protected: void showEvent(QShowEvent *) override; private: void reloadQmlSource(); - Q_SLOT void handleExpandedChanged(); private: QPointer m_statesEditorView; diff --git a/src/plugins/qmldesigner/designercore/include/viewmanager.h b/src/plugins/qmldesigner/designercore/include/viewmanager.h index af4bf8bb24..114c143e6a 100644 --- a/src/plugins/qmldesigner/designercore/include/viewmanager.h +++ b/src/plugins/qmldesigner/designercore/include/viewmanager.h @@ -94,8 +94,6 @@ public: DesignerActionManager &designerActionManager(); const DesignerActionManager &designerActionManager() const; - void toggleStatesViewExpanded(); - void qmlJSEditorContextHelp(const Core::IContext::HelpCallback &callback) const; DesignDocument *currentDesignDocument() const; diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp index c20ecf4b61..01e5f3e4c6 100644 --- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp @@ -405,11 +405,6 @@ const DesignerActionManager &ViewManager::designerActionManager() const return d->designerActionManagerView.designerActionManager(); } -void ViewManager::toggleStatesViewExpanded() -{ - d->statesEditorView.toggleStatesViewExpanded(); -} - void ViewManager::qmlJSEditorContextHelp(const Core::IContext::HelpCallback &callback) const { d->textEditorView.qmlJSEditorContextHelp(callback); diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index 08788ca5be..8ecaaa6edd 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -72,7 +72,6 @@ void DesignerSettings::fromSettings(QSettings *settings) restoreValue(settings, DesignerSettingsKey::FORWARD_PUPPET_OUTPUT, QString()); restoreValue(settings, DesignerSettingsKey::REFORMAT_UI_QML_FILES, true); restoreValue(settings, DesignerSettingsKey::IGNORE_DEVICE_PIXEL_RATIO, false); - restoreValue(settings, DesignerSettingsKey::STATESEDITOR_EXPANDED, true); restoreValue(settings, DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, true); restoreValue(settings, DesignerSettingsKey::NAVIGATOR_REVERSE_ITEM_ORDER, false); restoreValue(settings, DesignerSettingsKey::STANDALONE_MODE, false); diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index 0afb86d6dd..bb25e2e04c 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -60,7 +60,6 @@ const char ENABLE_MODEL_EXCEPTION_OUTPUT[] = "WarnException"; const char PUPPET_KILL_TIMEOUT[] = "PuppetKillTimeout"; const char DEBUG_PUPPET[] = "DebugPuppet"; const char FORWARD_PUPPET_OUTPUT[] = "ForwardPuppetOutput"; -const char STATESEDITOR_EXPANDED[] = "StatesEditorExpanded"; const char NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS[] = "NavigatorShowOnlyVisibleItems"; const char NAVIGATOR_REVERSE_ITEM_ORDER[] = "NavigatorReverseItemOrder"; const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These settings are not exposed in ui. */ diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index 25d1c27c47..e82e7a04c0 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -69,7 +69,6 @@ ShortCutManager::ShortCutManager() m_copyAction(tr("&Copy")), m_pasteAction(tr("&Paste")), m_selectAllAction(tr("Select &All")), - m_collapseExpandStatesAction(tr("Toggle States")), m_escapeAction(this) { @@ -97,10 +96,6 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex connect(&m_selectAllAction,&QAction::triggered, this, &ShortCutManager::selectAll); - connect(&m_collapseExpandStatesAction, &QAction::triggered, [] { - QmlDesignerPlugin::instance()->viewManager().toggleStatesViewExpanded(); - }); - // Revert to saved Core::EditorManager *em = Core::EditorManager::instance(); Core::ActionManager::registerAction(&m_revertToSavedAction,Core::Constants::REVERTTOSAVED, qmlDesignerMainContext); @@ -188,13 +183,6 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex command->setDefaultKeySequence(QKeySequence::SelectAll); editMenu->addAction(command, Core::Constants::G_EDIT_SELECTALL); - Core::ActionContainer *viewsMenu = Core::ActionManager::actionContainer(Core::Constants::M_VIEW_VIEWS); - - command = Core::ActionManager::registerAction(&m_collapseExpandStatesAction, Constants::TOGGLE_STATES_EDITOR, qmlDesignerMainContext); - command->setAttribute(Core::Command::CA_Hide); - command->setDefaultKeySequence(QKeySequence("Ctrl+Alt+s")); - viewsMenu->addAction(command); - /* Registering disabled action for Escape, because Qt Quick does not support shortcut overrides. */ command = Core::ActionManager::registerAction(&m_escapeAction, Core::Constants::S_RETURNTOEDITOR, qmlDesignerMainContext); command->setDefaultKeySequence(QKeySequence(Qt::Key_Escape)); diff --git a/src/plugins/qmldesigner/shortcutmanager.h b/src/plugins/qmldesigner/shortcutmanager.h index 6e5b5ec23b..4bc4ae5f84 100644 --- a/src/plugins/qmldesigner/shortcutmanager.h +++ b/src/plugins/qmldesigner/shortcutmanager.h @@ -83,7 +83,6 @@ private: QAction m_copyAction; QAction m_pasteAction; QAction m_selectAllAction; - QAction m_collapseExpandStatesAction; QAction m_escapeAction; }; -- cgit v1.2.3