From d52cb22b441d1d95e06814506e63db4884831477 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 11 Jun 2020 18:35:46 +0200 Subject: [PATCH] QmlDesigner: Add fit root to screen button * Add fit root to screen action to designer actions * Add button to form editor taskbar to trigger the action * Add additional zoom levels Task-number: QDS-2234 Change-Id: I1310da8ee9cfa608ed0c28f8bff769d320f588c3 Reviewed-by: Thomas Hartmann --- .../componentcore/componentcore_constants.h | 5 +++++ .../componentcore/designeractionmanager.cpp | 10 +++++++++ .../componentcore/modelnodeoperations.cpp | 8 +++++++ .../componentcore/modelnodeoperations.h | 1 + .../components/componentcore/zoomaction.cpp | 22 +++++++++++++++---- .../components/componentcore/zoomaction.h | 3 +++ .../components/formeditor/formeditorview.cpp | 22 +++++++++++++++++++ 7 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 792666ec364..e6ecc114b73 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -83,6 +83,7 @@ const char decreaseIndexOfStackedContainerCommandId[] = "DecreaseIndexOfStackedC const char flowAssignEffectCommandId[] = "AssignFlowEffect"; const char flowAssignCustomEffectCommandId[] = "AssignFlowCustomEffect"; const char addToGroupItemCommandId[] = "AddToGroupItem"; +const char fitRootToScreenCommandId[] = "FitRootToScreen"; const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection"); const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect"); @@ -155,6 +156,8 @@ const char layoutFillHeightDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContext const char flowAssignEffectDisplayName[] = "Assign FlowEffect "; const char flowAssignCustomEffectDisplayName[] = "Assign Custom FlowEffect "; +const char fitRootToScreenDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit root to screen"); + const char raiseToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Raise selected item."); const char lowerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Lower selected item."); @@ -173,6 +176,8 @@ const char decreaseIndexOfStackedContainerToolTip[] = QT_TRANSLATE_NOOP("QmlDesi const char addItemToStackedContainerToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add item to stacked container."); const char addFlowActionToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add flow action."); +const char fitRootToScreenToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit the root element inside the available space."); + const int priorityFirst = 280; const int prioritySelectionCategory = 220; const int priorityQmlPreviewCategory = 200; diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 2dbf8b00b44..ceb8ddcdd0b 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -821,6 +821,16 @@ void DesignerActionManager::createDefaultDesignerActions() &resetSize, &selectionNotEmptyAndHasWidthOrHeightProperty)); + addDesignerAction(new ModelNodeAction( + fitRootToScreenCommandId, + fitRootToScreenDisplayName, + Utils::Icon({{":/utils/images/fittoview.png", Utils::Theme::IconsBaseColor}}).icon(), + fitRootToScreenToolTip, + genericToolBarCategory, + QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_0), + 182, + &fitRootToScreen)); + addDesignerAction(new SeperatorDesignerAction(editCategory, 170)); addDesignerAction(new VisiblityModelNodeAction( diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index e91fde43599..c73f48d6af0 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -344,6 +344,14 @@ void resetPosition(const SelectionContext &selectionState) }); } +void fitRootToScreen(const SelectionContext &selectionState) +{ + if (!selectionState.view()) + return; + + selectionState.view()->emitCustomNotification(QStringLiteral("fit root to screen")); +} + void goIntoComponentOperation(const SelectionContext &selectionState) { goIntoComponent(selectionState.currentSingleSelectedNode()); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index afd8416bf9f..b8bbc0e1c90 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -49,6 +49,7 @@ void setFillWidth(const SelectionContext &selectionState); void setFillHeight(const SelectionContext &selectionState); void resetSize(const SelectionContext &selectionState); void resetPosition(const SelectionContext &selectionState); +void fitRootToScreen(const SelectionContext &selectionState); void goIntoComponentOperation(const SelectionContext &selectionState); void setId(const SelectionContext &selectionState); void resetZ(const SelectionContext &selectionState); diff --git a/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp b/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp index 95ed102f82b..4f1d1c3da90 100644 --- a/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp @@ -30,7 +30,7 @@ namespace QmlDesigner { -const int defaultZoomIndex = 11; +const int defaultZoomIndex = 13; ZoomAction::ZoomAction(QObject *parent) : QWidgetAction(parent), @@ -69,14 +69,19 @@ void ZoomAction::setZoomLevel(float zoomLevel) if (qFuzzyCompare(m_zoomLevel, zoomLevel)) return; + forceZoomLevel(zoomLevel); +} + +void ZoomAction::forceZoomLevel(float zoomLevel) +{ m_zoomLevel = qBound(0.01f, zoomLevel, 16.0f); emit zoomLevelChanged(m_zoomLevel); } //initial m_zoomLevel and m_currentComboBoxIndex -const QVector s_zoomFactors = {0.01f, 0.02f, 0.05f, 0.0625f, 0.125f, 0.25f, - 0.33f, 0.5f, 0.66f, 0.75f, 0.9f, 1.0f, 1.25f, - 1.5f, 1.75f, 2.0f, 3.0f, 4.0f, 6.0f, 8.0f, 10.0f, 16.0f }; +const QVector s_zoomFactors = {0.01f, 0.02f, 0.05f, 0.0625f, 0.1f, 0.125f, 0.2f, 0.25f, + 0.33f, 0.5f, 0.66f, 0.75f, 0.9f, 1.0f, 1.1f, 1.25f, 1.33f, + 1.5f, 1.66f, 1.75f, 2.0f, 3.0f, 4.0f, 6.0f, 8.0f, 10.0f, 16.0f }; int getZoomIndex(float zoom) { @@ -87,6 +92,15 @@ int getZoomIndex(float zoom) return -1; } +float ZoomAction::getClosestZoomLevel(float zoomLevel) +{ + int i = 0; + while (i < s_zoomFactors.size() && s_zoomFactors[i] < zoomLevel) + ++i; + + return s_zoomFactors[qBound(0, i - 1, s_zoomFactors.size() - 1)]; +} + QWidget *ZoomAction::createWidget(QWidget *parent) { auto comboBox = new QComboBox(parent); diff --git a/src/plugins/qmldesigner/components/componentcore/zoomaction.h b/src/plugins/qmldesigner/components/componentcore/zoomaction.h index 1b178343e8d..bd46f915d91 100644 --- a/src/plugins/qmldesigner/components/componentcore/zoomaction.h +++ b/src/plugins/qmldesigner/components/componentcore/zoomaction.h @@ -48,6 +48,9 @@ public: void zoomOut(); void resetZoomLevel(); void setZoomLevel(float zoomLevel); + void forceZoomLevel(float zoomLevel); + + static float getClosestZoomLevel(float zoomLevel); protected: QWidget *createWidget(QWidget *parent) override; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index c7c34329c4a..db2d10849f4 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -448,6 +448,28 @@ void FormEditorView::customNotification(const AbstractView * /*view*/, const QSt m_dragTool->clearMoveDelay(); if (identifier == QLatin1String("reset QmlPuppet")) temporaryBlockView(); + if (identifier == QLatin1String("fit root to screen")) { + + if (QmlItemNode(rootModelNode()).isFlowView()) { + QRectF boundingRect; + for (QGraphicsItem *item : scene()->items()) { + if (auto formEditorItem = FormEditorItem::fromQGraphicsItem(item)) { + if (!formEditorItem->qmlItemNode().modelNode().isRootNode() + && !formEditorItem->sceneBoundingRect().isNull()) + boundingRect = boundingRect.united(formEditorItem->sceneBoundingRect()); + } + } + m_formEditorWidget->graphicsView()->fitInView(boundingRect, + Qt::KeepAspectRatio); + } else { + m_formEditorWidget->graphicsView()->fitInView(m_formEditorWidget->rootItemRect(), + Qt::KeepAspectRatio); + } + + const qreal scaleFactor = m_formEditorWidget->graphicsView()->viewportTransform().m11(); + float zoomLevel = ZoomAction::getClosestZoomLevel(scaleFactor); + m_formEditorWidget->zoomAction()->forceZoomLevel(zoomLevel); + } } AbstractFormEditorTool *FormEditorView::currentTool() const