forked from qt-creator/qt-creator
QmlDesigner: Rotation Tool
- Added Rotation Tool to Form Editor - Rotation Tool is activated on items corners - Supports alt and shift modifiers - Works with MCU projects - Uses new rotation icon Task: QDS-2881 Change-Id: I9905968b7ac31d008184e343294fbd33cdb45c1c Reviewed-by: Marco Bubke <marco.bubke@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -265,6 +265,11 @@ extend_qtc_plugin(QmlDesigner
|
||||
resizeindicator.cpp resizeindicator.h
|
||||
resizemanipulator.cpp resizemanipulator.h
|
||||
resizetool.cpp resizetool.h
|
||||
rotationtool.cpp rotationtool.h
|
||||
rotationindicator.cpp rotationindicator.h
|
||||
rotationcontroller.cpp rotationcontroller.h
|
||||
rotationhandleitem.cpp rotationhandleitem.h
|
||||
rotationmanipulator.cpp rotationmanipulator.h
|
||||
rubberbandselectionmanipulator.cpp rubberbandselectionmanipulator.h
|
||||
scaleitem.cpp scaleitem.h
|
||||
scalemanipulator.cpp scalemanipulator.h
|
||||
|
||||
@@ -24,6 +24,11 @@ SOURCES += formeditoritem.cpp \
|
||||
scaleitem.cpp \
|
||||
resizecontroller.cpp \
|
||||
resizehandleitem.cpp \
|
||||
rotationtool.cpp \
|
||||
rotationindicator.cpp \
|
||||
rotationcontroller.cpp \
|
||||
rotationhandleitem.cpp \
|
||||
rotationmanipulator.cpp \
|
||||
dragtool.cpp \
|
||||
toolbox.cpp \
|
||||
formeditorgraphicsview.cpp \
|
||||
@@ -64,6 +69,11 @@ HEADERS += formeditorscene.h \
|
||||
scaleitem.h \
|
||||
resizecontroller.h \
|
||||
resizehandleitem.h \
|
||||
rotationtool.h \
|
||||
rotationindicator.h \
|
||||
rotationcontroller.h \
|
||||
rotationhandleitem.h \
|
||||
rotationmanipulator.h \
|
||||
dragtool.h \
|
||||
toolbox.h \
|
||||
formeditorgraphicsview.h \
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "formeditorview.h"
|
||||
#include "nodeinstanceview.h"
|
||||
#include "selectiontool.h"
|
||||
#include "rotationtool.h"
|
||||
#include "movetool.h"
|
||||
#include "resizetool.h"
|
||||
#include "dragtool.h"
|
||||
@@ -207,6 +208,7 @@ void FormEditorView::createFormEditorWidget()
|
||||
|
||||
m_moveTool = std::make_unique<MoveTool>(this);
|
||||
m_selectionTool = std::make_unique<SelectionTool>(this);
|
||||
m_rotationTool = std::make_unique<RotationTool>(this);
|
||||
m_resizeTool = std::make_unique<ResizeTool>(this);
|
||||
m_dragTool = std::make_unique<DragTool>(this);
|
||||
|
||||
@@ -248,6 +250,7 @@ void FormEditorView::cleanupToolsAndScene()
|
||||
{
|
||||
m_currentTool->setItems(QList<FormEditorItem *>());
|
||||
m_selectionTool->clear();
|
||||
m_rotationTool->clear();
|
||||
m_moveTool->clear();
|
||||
m_resizeTool->clear();
|
||||
m_dragTool->clear();
|
||||
@@ -548,6 +551,12 @@ void FormEditorView::resetToSelectionTool()
|
||||
changeCurrentToolTo(m_selectionTool.get());
|
||||
}
|
||||
|
||||
void FormEditorView::changeToRotationTool() {
|
||||
if (m_currentTool == m_rotationTool.get())
|
||||
return;
|
||||
changeCurrentToolTo(m_rotationTool.get());
|
||||
}
|
||||
|
||||
void FormEditorView::changeToResizeTool()
|
||||
{
|
||||
if (m_currentTool == m_resizeTool.get())
|
||||
@@ -559,6 +568,7 @@ void FormEditorView::changeToTransformTools()
|
||||
{
|
||||
if (m_currentTool == m_moveTool.get() ||
|
||||
m_currentTool == m_resizeTool.get() ||
|
||||
m_currentTool == m_rotationTool.get() ||
|
||||
m_currentTool == m_selectionTool.get())
|
||||
return;
|
||||
changeToSelectionTool();
|
||||
@@ -854,6 +864,7 @@ void FormEditorView::reset()
|
||||
void FormEditorView::delayedReset()
|
||||
{
|
||||
m_selectionTool->clear();
|
||||
m_rotationTool->clear();
|
||||
m_moveTool->clear();
|
||||
m_resizeTool->clear();
|
||||
m_dragTool->clear();
|
||||
|
||||
@@ -47,6 +47,7 @@ class AbstractFormEditorTool;
|
||||
class AbstractCustomTool;
|
||||
class MoveTool;
|
||||
class SelectionTool;
|
||||
class RotationTool;
|
||||
class ResizeTool;
|
||||
class DragTool;
|
||||
class ItemLibraryEntry;
|
||||
@@ -104,6 +105,7 @@ public:
|
||||
void changeToSelectionTool();
|
||||
void changeToSelectionTool(QGraphicsSceneMouseEvent *event);
|
||||
void resetToSelectionTool();
|
||||
void changeToRotationTool();
|
||||
void changeToResizeTool();
|
||||
void changeToTransformTools();
|
||||
void changeToCustomTool();
|
||||
@@ -152,6 +154,7 @@ private:
|
||||
QList<AbstractCustomTool*> m_customToolList;
|
||||
std::unique_ptr<MoveTool> m_moveTool;
|
||||
std::unique_ptr<SelectionTool> m_selectionTool;
|
||||
std::unique_ptr<RotationTool> m_rotationTool;
|
||||
std::unique_ptr<ResizeTool> m_resizeTool;
|
||||
std::unique_ptr<DragTool> m_dragTool;
|
||||
AbstractFormEditorTool *m_currentTool = nullptr;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "formeditorgraphicsview.h"
|
||||
|
||||
#include "resizehandleitem.h"
|
||||
#include "rotationhandleitem.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
@@ -46,6 +47,7 @@ MoveTool::MoveTool(FormEditorView *editorView)
|
||||
m_moveManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
|
||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_rotationIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
@@ -61,6 +63,7 @@ void MoveTool::clear()
|
||||
m_movingItems.clear();
|
||||
m_selectionIndicator.clear();
|
||||
m_resizeIndicator.clear();
|
||||
m_rotationIndicator.clear();
|
||||
m_anchorIndicator.clear();
|
||||
m_bindingIndicator.clear();
|
||||
m_contentNotEditableIndicator.clear();
|
||||
@@ -100,6 +103,7 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||
|
||||
m_selectionIndicator.hide();
|
||||
m_resizeIndicator.hide();
|
||||
m_rotationIndicator.hide();
|
||||
m_anchorIndicator.hide();
|
||||
m_bindingIndicator.hide();
|
||||
|
||||
@@ -135,6 +139,12 @@ void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||
return;
|
||||
}
|
||||
|
||||
RotationHandleItem* rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||
if (rotationHandle) {
|
||||
view()->changeToRotationTool();
|
||||
return;
|
||||
}
|
||||
|
||||
if (view()->hasSingleSelectedModelNode() && selectedItemCursorInMovableArea(event->scenePos()))
|
||||
return;
|
||||
|
||||
@@ -182,6 +192,7 @@ void MoveTool::keyPressEvent(QKeyEvent *event)
|
||||
m_moveManipulator.setItems(movableItems);
|
||||
// m_selectionIndicator.hide();
|
||||
m_resizeIndicator.hide();
|
||||
m_rotationIndicator.hide();
|
||||
m_anchorIndicator.hide();
|
||||
m_bindingIndicator.hide();
|
||||
m_moveManipulator.beginRewriterTransaction();
|
||||
@@ -215,6 +226,7 @@ void MoveTool::keyReleaseEvent(QKeyEvent *keyEvent)
|
||||
m_moveManipulator.clear();
|
||||
// m_selectionIndicator.show();
|
||||
m_resizeIndicator.show();
|
||||
m_rotationIndicator.show();
|
||||
m_anchorIndicator.show();
|
||||
m_bindingIndicator.show();
|
||||
}
|
||||
@@ -241,6 +253,7 @@ void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
||||
|
||||
m_selectionIndicator.show();
|
||||
m_resizeIndicator.show();
|
||||
m_rotationIndicator.show();
|
||||
m_anchorIndicator.show();
|
||||
m_bindingIndicator.show();
|
||||
m_movingItems.clear();
|
||||
@@ -266,6 +279,7 @@ void MoveTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
m_selectionIndicator.setItems(movingItems(itemList));
|
||||
m_resizeIndicator.setItems(itemList);
|
||||
m_rotationIndicator.setItems(itemList);
|
||||
m_anchorIndicator.setItems(itemList);
|
||||
m_bindingIndicator.setItems(itemList);
|
||||
updateMoveManipulator();
|
||||
@@ -386,6 +400,7 @@ void MoveTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
|
||||
m_selectionIndicator.updateItems(selectedItemList);
|
||||
m_resizeIndicator.updateItems(selectedItemList);
|
||||
m_rotationIndicator.updateItems(selectedItemList);
|
||||
m_anchorIndicator.updateItems(selectedItemList);
|
||||
m_bindingIndicator.updateItems(selectedItemList);
|
||||
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "movemanipulator.h"
|
||||
#include "selectionindicator.h"
|
||||
#include "resizeindicator.h"
|
||||
#include "rotationindicator.h"
|
||||
#include "anchorindicator.h"
|
||||
#include "bindingindicator.h"
|
||||
#include "contentnoteditableindicator.h"
|
||||
@@ -84,6 +85,7 @@ private:
|
||||
MoveManipulator m_moveManipulator;
|
||||
SelectionIndicator m_selectionIndicator;
|
||||
ResizeIndicator m_resizeIndicator;
|
||||
RotationIndicator m_rotationIndicator;
|
||||
AnchorIndicator m_anchorIndicator;
|
||||
BindingIndicator m_bindingIndicator;
|
||||
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
||||
|
||||
@@ -57,7 +57,7 @@ void ResizeIndicator::clear()
|
||||
m_itemControllerHash.clear();
|
||||
}
|
||||
|
||||
bool itemIsResizable(const QmlItemNode &qmlItemNode)
|
||||
static bool itemIsResizable(const QmlItemNode &qmlItemNode)
|
||||
{
|
||||
return qmlItemNode.isValid()
|
||||
&& qmlItemNode.instanceIsResizable()
|
||||
|
||||
@@ -38,11 +38,12 @@
|
||||
namespace QmlDesigner {
|
||||
|
||||
ResizeTool::ResizeTool(FormEditorView *editorView)
|
||||
: AbstractFormEditorTool(editorView),
|
||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_resizeManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
||||
: AbstractFormEditorTool(editorView)
|
||||
, m_selectionIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_resizeIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_anchorIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_rotationIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_resizeManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,6 +62,7 @@ void ResizeTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
|
||||
m_resizeManipulator.begin(event->scenePos());
|
||||
m_resizeIndicator.hide();
|
||||
m_anchorIndicator.hide();
|
||||
m_rotationIndicator.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +115,7 @@ void ResizeTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
||||
m_selectionIndicator.show();
|
||||
m_resizeIndicator.show();
|
||||
m_anchorIndicator.show();
|
||||
m_rotationIndicator.show();
|
||||
m_resizeManipulator.end(generateUseSnapping(event->modifiers()));
|
||||
}
|
||||
|
||||
@@ -171,6 +174,7 @@ void ResizeTool::selectedItemsChanged(const QList<FormEditorItem*> & /*itemList*
|
||||
m_selectionIndicator.setItems(items());
|
||||
m_resizeIndicator.setItems(items());
|
||||
m_anchorIndicator.setItems(items());
|
||||
m_rotationIndicator.setItems(items());
|
||||
}
|
||||
|
||||
void ResizeTool::clear()
|
||||
@@ -178,6 +182,7 @@ void ResizeTool::clear()
|
||||
m_selectionIndicator.clear();
|
||||
m_resizeIndicator.clear();
|
||||
m_anchorIndicator.clear();
|
||||
m_rotationIndicator.clear();
|
||||
m_resizeManipulator.clear();
|
||||
}
|
||||
|
||||
@@ -188,6 +193,7 @@ void ResizeTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
m_selectionIndicator.updateItems(selectedItemList);
|
||||
m_resizeIndicator.updateItems(selectedItemList);
|
||||
m_anchorIndicator.updateItems(selectedItemList);
|
||||
m_rotationIndicator.updateItems(selectedItemList);
|
||||
}
|
||||
|
||||
void ResizeTool::instancesCompleted(const QList<FormEditorItem*> &/*itemList*/)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "selectionindicator.h"
|
||||
#include "resizeindicator.h"
|
||||
#include "anchorindicator.h"
|
||||
#include "rotationindicator.h"
|
||||
#include "resizemanipulator.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -69,6 +70,7 @@ private:
|
||||
SelectionIndicator m_selectionIndicator;
|
||||
ResizeIndicator m_resizeIndicator;
|
||||
AnchorIndicator m_anchorIndicator;
|
||||
RotationIndicator m_rotationIndicator;
|
||||
ResizeManipulator m_resizeManipulator;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "rotationcontroller.h"
|
||||
|
||||
#include "formeditoritem.h"
|
||||
#include "layeritem.h"
|
||||
|
||||
#include <rotationhandleitem.h>
|
||||
#include <QCursor>
|
||||
#include <QGraphicsScene>
|
||||
|
||||
#include <utils/stylehelper.h>
|
||||
#include <theme.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class RotationControllerData
|
||||
{
|
||||
public:
|
||||
RotationControllerData(LayerItem *layerItem,
|
||||
FormEditorItem *formEditorItem);
|
||||
RotationControllerData(const RotationControllerData &other);
|
||||
~RotationControllerData();
|
||||
|
||||
|
||||
QPointer<LayerItem> layerItem;
|
||||
FormEditorItem *formEditorItem = nullptr;
|
||||
QSharedPointer<RotationHandleItem> topLeftItem;
|
||||
QSharedPointer<RotationHandleItem> topRightItem;
|
||||
QSharedPointer<RotationHandleItem> bottomLeftItem;
|
||||
QSharedPointer<RotationHandleItem> bottomRightItem;
|
||||
};
|
||||
|
||||
RotationControllerData::RotationControllerData(LayerItem *layerItem, FormEditorItem *formEditorItem)
|
||||
: layerItem(layerItem)
|
||||
, formEditorItem(formEditorItem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RotationControllerData::RotationControllerData(const RotationControllerData &other) = default;
|
||||
|
||||
RotationControllerData::~RotationControllerData()
|
||||
{
|
||||
if (layerItem) {
|
||||
QGraphicsScene *scene = layerItem->scene();
|
||||
scene->removeItem(topLeftItem.data());
|
||||
scene->removeItem(topRightItem.data());
|
||||
scene->removeItem(bottomLeftItem.data());
|
||||
scene->removeItem(bottomRightItem.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RotationController::RotationController()
|
||||
: m_data(new RotationControllerData(nullptr, nullptr))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RotationController::RotationController(const QSharedPointer<RotationControllerData> &data)
|
||||
: m_data(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RotationController::RotationController(LayerItem *layerItem, FormEditorItem *formEditorItem)
|
||||
: m_data(new RotationControllerData(layerItem, formEditorItem))
|
||||
{
|
||||
QCursor rotationCursor = getRotationCursor();
|
||||
|
||||
m_data->topLeftItem = QSharedPointer<RotationHandleItem>(new RotationHandleItem(layerItem, *this));
|
||||
m_data->topLeftItem->setZValue(302);
|
||||
m_data->topLeftItem->setCursor(rotationCursor);
|
||||
|
||||
m_data->topRightItem = QSharedPointer<RotationHandleItem>(new RotationHandleItem(layerItem, *this));
|
||||
m_data->topRightItem->setZValue(301);
|
||||
m_data->topRightItem->setCursor(rotationCursor);
|
||||
|
||||
m_data->bottomLeftItem = QSharedPointer<RotationHandleItem>(new RotationHandleItem(layerItem, *this));
|
||||
m_data->bottomLeftItem->setZValue(301);
|
||||
m_data->bottomLeftItem->setCursor(rotationCursor);
|
||||
|
||||
m_data->bottomRightItem = QSharedPointer<RotationHandleItem>(new RotationHandleItem(layerItem, *this));
|
||||
m_data->bottomRightItem->setZValue(305);
|
||||
m_data->bottomRightItem->setCursor(rotationCursor);
|
||||
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
RotationController::RotationController(const RotationController &other) = default;
|
||||
|
||||
RotationController::RotationController(const WeakRotationController &rotationController)
|
||||
: m_data(rotationController.m_data.toStrongRef())
|
||||
{
|
||||
}
|
||||
|
||||
RotationController::~RotationController() = default;
|
||||
|
||||
RotationController &RotationController::operator =(const RotationController &other)
|
||||
{
|
||||
if (this != &other)
|
||||
m_data = other.m_data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool RotationController::isValid() const
|
||||
{
|
||||
return m_data->formEditorItem && m_data->formEditorItem->qmlItemNode().isValid();
|
||||
}
|
||||
|
||||
void RotationController::show()
|
||||
{
|
||||
m_data->topLeftItem->show();
|
||||
m_data->topRightItem->show();
|
||||
m_data->bottomLeftItem->show();
|
||||
m_data->bottomRightItem->show();
|
||||
}
|
||||
void RotationController::hide()
|
||||
{
|
||||
m_data->topLeftItem->hide();
|
||||
m_data->topRightItem->hide();
|
||||
m_data->bottomLeftItem->hide();
|
||||
m_data->bottomRightItem->hide();
|
||||
}
|
||||
|
||||
|
||||
void RotationController::updatePosition()
|
||||
{
|
||||
if (isValid()) {
|
||||
|
||||
QRectF boundingRect = m_data->formEditorItem->qmlItemNode().instanceBoundingRect();
|
||||
QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
boundingRect.topLeft()));
|
||||
QPointF topRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
boundingRect.topRight()));
|
||||
QPointF bottomLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
boundingRect.bottomLeft()));
|
||||
QPointF bottomRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
boundingRect.bottomRight()));
|
||||
|
||||
const qreal rotation = m_data->formEditorItem->qmlItemNode().rotation();
|
||||
|
||||
m_data->topRightItem->setHandlePosition(topRightPointInLayerSpace, boundingRect.topRight(), rotation);
|
||||
m_data->topLeftItem->setHandlePosition(topLeftPointInLayerSpace, boundingRect.topLeft(), rotation);
|
||||
m_data->bottomLeftItem->setHandlePosition(bottomLeftPointInLayerSpace, boundingRect.bottomLeft(), rotation);
|
||||
m_data->bottomRightItem->setHandlePosition(bottomRightPointInLayerSpace, boundingRect.bottomRight(), rotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FormEditorItem* RotationController::formEditorItem() const
|
||||
{
|
||||
return m_data->formEditorItem;
|
||||
}
|
||||
|
||||
bool RotationController::isTopLeftHandle(const RotationHandleItem *handle) const
|
||||
{
|
||||
return handle == m_data->topLeftItem;
|
||||
}
|
||||
|
||||
bool RotationController::isTopRightHandle(const RotationHandleItem *handle) const
|
||||
{
|
||||
return handle == m_data->topRightItem;
|
||||
}
|
||||
|
||||
bool RotationController::isBottomLeftHandle(const RotationHandleItem *handle) const
|
||||
{
|
||||
return handle == m_data->bottomLeftItem;
|
||||
}
|
||||
|
||||
bool RotationController::isBottomRightHandle(const RotationHandleItem *handle) const
|
||||
{
|
||||
return handle == m_data->bottomRightItem;
|
||||
}
|
||||
|
||||
QCursor RotationController::getRotationCursor() const
|
||||
{
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
const int cursorSize = 32; //32 is cursor recommended size
|
||||
|
||||
QIcon rotationIcon = Utils::StyleHelper::getIconFromIconFont(
|
||||
fontName,
|
||||
Theme::getIconUnicode(Theme::rotation),
|
||||
cursorSize, cursorSize,
|
||||
Qt::white);
|
||||
|
||||
return QCursor(rotationIcon.pixmap(cursorSize, cursorSize));
|
||||
}
|
||||
|
||||
WeakRotationController RotationController::toWeakRotationController() const
|
||||
{
|
||||
return WeakRotationController(*this);
|
||||
}
|
||||
|
||||
WeakRotationController::WeakRotationController() = default;
|
||||
|
||||
WeakRotationController::WeakRotationController(const WeakRotationController &rotationController) = default;
|
||||
|
||||
WeakRotationController::WeakRotationController(const RotationController &rotationController)
|
||||
: m_data(rotationController.m_data.toWeakRef())
|
||||
{
|
||||
}
|
||||
|
||||
WeakRotationController::~WeakRotationController() = default;
|
||||
|
||||
WeakRotationController &WeakRotationController::operator =(const WeakRotationController &other)
|
||||
{
|
||||
if (m_data != other.m_data)
|
||||
m_data = other.m_data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RotationController WeakRotationController::toRotationController() const
|
||||
{
|
||||
return RotationController(*this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QWeakPointer>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class FormEditorItem;
|
||||
class LayerItem;
|
||||
class RotationHandleItem;
|
||||
class RotationControllerData;
|
||||
class WeakRotationController;
|
||||
|
||||
class RotationController
|
||||
{
|
||||
friend class WeakRotationController;
|
||||
public:
|
||||
RotationController();
|
||||
RotationController(LayerItem *layerItem, FormEditorItem *formEditorItem);
|
||||
RotationController(const RotationController &rotationController);
|
||||
RotationController(const WeakRotationController &rotationController);
|
||||
~RotationController();
|
||||
|
||||
RotationController& operator=(const RotationController &other);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
|
||||
void updatePosition();
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
FormEditorItem *formEditorItem() const;
|
||||
|
||||
bool isTopLeftHandle(const RotationHandleItem *handle) const;
|
||||
bool isTopRightHandle(const RotationHandleItem *handle) const;
|
||||
bool isBottomLeftHandle(const RotationHandleItem *handle) const;
|
||||
bool isBottomRightHandle(const RotationHandleItem *handle) const;
|
||||
|
||||
WeakRotationController toWeakRotationController() const;
|
||||
|
||||
private:
|
||||
RotationController(const QSharedPointer<RotationControllerData> &data);
|
||||
|
||||
QCursor getRotationCursor() const;
|
||||
|
||||
private:
|
||||
QSharedPointer<RotationControllerData> m_data;
|
||||
};
|
||||
|
||||
class WeakRotationController
|
||||
{
|
||||
friend class RotationController;
|
||||
public:
|
||||
WeakRotationController();
|
||||
WeakRotationController(const WeakRotationController &rotationController);
|
||||
WeakRotationController(const RotationController &rotationController);
|
||||
~WeakRotationController();
|
||||
|
||||
WeakRotationController& operator=(const WeakRotationController &other);
|
||||
|
||||
RotationController toRotationController() const;
|
||||
|
||||
private: // variables
|
||||
QWeakPointer<RotationControllerData> m_data;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "rotationhandleitem.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
RotationHandleItem::RotationHandleItem(QGraphicsItem *parent, const RotationController &rotationController)
|
||||
: QGraphicsItem(parent)
|
||||
, m_weakRotationController(rotationController.toWeakRotationController())
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
|
||||
setAcceptedMouseButtons(Qt::NoButton);
|
||||
}
|
||||
|
||||
RotationHandleItem::~RotationHandleItem() = default;
|
||||
|
||||
void RotationHandleItem::setHandlePosition(const QPointF & globalPosition, const QPointF & itemSpacePosition, const qreal rotation)
|
||||
{
|
||||
m_itemSpacePosition = itemSpacePosition;
|
||||
setRotation(rotation);
|
||||
setPos(globalPosition);
|
||||
}
|
||||
|
||||
QRectF RotationHandleItem::boundingRect() const
|
||||
{
|
||||
QRectF rectangle;
|
||||
|
||||
if (isTopLeftHandle()) {
|
||||
rectangle = { -30., -30., 27., 27.};
|
||||
}
|
||||
else if (isTopRightHandle()) {
|
||||
rectangle = { 3., -30., 27., 27.};
|
||||
}
|
||||
else if (isBottomLeftHandle()) {
|
||||
rectangle = { -30., 3., 27., 27.};
|
||||
}
|
||||
else if (isBottomRightHandle()) {
|
||||
rectangle = { 3., 3., 27., 27.};
|
||||
}
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
void RotationHandleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */)
|
||||
{
|
||||
painter->save();
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidth(1);
|
||||
pen.setCosmetic(true);
|
||||
painter->setPen(pen);
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->setBrush(QColor(255, 255, 255));
|
||||
painter->drawRect(QRectF(-3., -3., 5., 5.));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
RotationController RotationHandleItem::rotationController() const
|
||||
{
|
||||
return RotationController(m_weakRotationController.toRotationController());
|
||||
}
|
||||
|
||||
RotationHandleItem* RotationHandleItem::fromGraphicsItem(QGraphicsItem *item)
|
||||
{
|
||||
return qgraphicsitem_cast<RotationHandleItem*>(item);
|
||||
}
|
||||
|
||||
bool RotationHandleItem::isTopLeftHandle() const
|
||||
{
|
||||
return rotationController().isTopLeftHandle(this);
|
||||
}
|
||||
|
||||
bool RotationHandleItem::isTopRightHandle() const
|
||||
{
|
||||
return rotationController().isTopRightHandle(this);
|
||||
}
|
||||
|
||||
bool RotationHandleItem::isBottomLeftHandle() const
|
||||
{
|
||||
return rotationController().isBottomLeftHandle(this);
|
||||
}
|
||||
|
||||
bool RotationHandleItem::isBottomRightHandle() const
|
||||
{
|
||||
return rotationController().isBottomRightHandle(this);
|
||||
}
|
||||
|
||||
QPointF RotationHandleItem::itemSpacePosition() const
|
||||
{
|
||||
return m_itemSpacePosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "rotationcontroller.h"
|
||||
|
||||
#include <qmldesignercorelib_global.h>
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT RotationHandleItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Type = 0xEBEB
|
||||
};
|
||||
|
||||
RotationHandleItem(QGraphicsItem *parent, const RotationController &rotationController);
|
||||
~RotationHandleItem() override;
|
||||
void setHandlePosition(const QPointF & globalPosition, const QPointF & itemSpacePosition, const qreal rotation);
|
||||
|
||||
int type() const override;
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
RotationController rotationController() const;
|
||||
|
||||
static RotationHandleItem* fromGraphicsItem(QGraphicsItem *item);
|
||||
|
||||
bool isTopLeftHandle() const;
|
||||
bool isTopRightHandle() const;
|
||||
bool isBottomLeftHandle() const;
|
||||
bool isBottomRightHandle() const;
|
||||
|
||||
QPointF itemSpacePosition() const;
|
||||
|
||||
private:
|
||||
WeakRotationController m_weakRotationController;
|
||||
QPointF m_itemSpacePosition;
|
||||
};
|
||||
|
||||
inline int RotationHandleItem::type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "rotationindicator.h"
|
||||
|
||||
#include "formeditoritem.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
RotationIndicator::RotationIndicator(LayerItem *layerItem)
|
||||
: m_layerItem(layerItem)
|
||||
{
|
||||
Q_ASSERT(layerItem);
|
||||
}
|
||||
|
||||
RotationIndicator::~RotationIndicator()
|
||||
{
|
||||
m_itemControllerHash.clear();
|
||||
}
|
||||
|
||||
void RotationIndicator::show()
|
||||
{
|
||||
for (RotationController controller : m_itemControllerHash)
|
||||
controller.show();
|
||||
}
|
||||
|
||||
void RotationIndicator::hide()
|
||||
{
|
||||
for (RotationController controller : m_itemControllerHash)
|
||||
controller.hide();
|
||||
}
|
||||
|
||||
void RotationIndicator::clear()
|
||||
{
|
||||
m_itemControllerHash.clear();
|
||||
}
|
||||
|
||||
static bool itemIsRotatable(const QmlItemNode &qmlItemNode)
|
||||
{
|
||||
return qmlItemNode.isValid()
|
||||
&& qmlItemNode.instanceIsResizable()
|
||||
&& qmlItemNode.modelIsMovable()
|
||||
&& qmlItemNode.modelIsRotatable()
|
||||
&& !qmlItemNode.instanceIsInLayoutable();
|
||||
}
|
||||
|
||||
void RotationIndicator::setItems(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
clear();
|
||||
|
||||
for (FormEditorItem *item : itemList) {
|
||||
if (item && itemIsRotatable(item->qmlItemNode())) {
|
||||
RotationController controller(m_layerItem, item);
|
||||
m_itemControllerHash.insert(item, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RotationIndicator::updateItems(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
for (FormEditorItem *item : itemList) {
|
||||
if (m_itemControllerHash.contains(item)) {
|
||||
if (!item || !itemIsRotatable(item->qmlItemNode())) {
|
||||
m_itemControllerHash.take(item);
|
||||
} else {
|
||||
RotationController controller(m_itemControllerHash.value(item));
|
||||
controller.updatePosition();
|
||||
}
|
||||
} else if (item && itemIsRotatable(item->qmlItemNode())) {
|
||||
RotationController controller(m_layerItem, item);
|
||||
m_itemControllerHash.insert(item, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "rotationcontroller.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QPair>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class FormEditorItem;
|
||||
class LayerItem;
|
||||
|
||||
class RotationIndicator
|
||||
{
|
||||
public:
|
||||
enum Orientation {
|
||||
Top = 1,
|
||||
Right = 2,
|
||||
Bottom = 4,
|
||||
Left = 8
|
||||
};
|
||||
|
||||
explicit RotationIndicator(LayerItem *layerItem);
|
||||
~RotationIndicator();
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void clear();
|
||||
|
||||
void setItems(const QList<FormEditorItem*> &itemList);
|
||||
void updateItems(const QList<FormEditorItem*> &itemList);
|
||||
|
||||
private:
|
||||
QHash<FormEditorItem*, RotationController> m_itemControllerHash;
|
||||
LayerItem *m_layerItem;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,260 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "rotationmanipulator.h"
|
||||
|
||||
#include "formeditoritem.h"
|
||||
#include "formeditorscene.h"
|
||||
#include "qmlanchors.h"
|
||||
#include <QDebug>
|
||||
#include <QtMath>
|
||||
#include "enumeration.h"
|
||||
#include "mathutils.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
RotationManipulator::RotationManipulator(LayerItem *layerItem, FormEditorView *view)
|
||||
: m_view(view)
|
||||
, m_beginTopMargin(0.0)
|
||||
, m_beginLeftMargin(0.0)
|
||||
, m_beginRightMargin(0.0)
|
||||
, m_beginBottomMargin(0.0)
|
||||
, m_layerItem(layerItem)
|
||||
{
|
||||
}
|
||||
|
||||
RotationManipulator::~RotationManipulator()
|
||||
{
|
||||
deleteSnapLines();
|
||||
}
|
||||
|
||||
void RotationManipulator::setHandle(RotationHandleItem *rotationHandle)
|
||||
{
|
||||
Q_ASSERT(rotationHandle);
|
||||
m_rotationHandle = rotationHandle;
|
||||
m_rotationController = rotationHandle->rotationController();
|
||||
Q_ASSERT(m_rotationController.isValid());
|
||||
}
|
||||
|
||||
void RotationManipulator::removeHandle()
|
||||
{
|
||||
m_rotationController = RotationController();
|
||||
m_rotationHandle = nullptr;
|
||||
}
|
||||
|
||||
void RotationManipulator::begin(const QPointF &/*beginPoint*/)
|
||||
{
|
||||
if (m_rotationController.isValid()) {
|
||||
m_isActive = true;
|
||||
m_beginBoundingRect = m_rotationController.formEditorItem()->qmlItemNode().instanceBoundingRect();
|
||||
m_beginFromContentItemToSceneTransform = m_rotationController.formEditorItem()->instanceSceneContentItemTransform();
|
||||
m_beginFromSceneToContentItemTransform = m_beginFromContentItemToSceneTransform.inverted();
|
||||
m_beginFromItemToSceneTransform = m_rotationController.formEditorItem()->instanceSceneTransform();
|
||||
m_beginToParentTransform = m_rotationController.formEditorItem()->qmlItemNode().instanceTransform();
|
||||
m_rewriterTransaction = m_view->beginRewriterTransaction(QByteArrayLiteral("RotationManipulator::begin"));
|
||||
m_rewriterTransaction.ignoreSemanticChecks();
|
||||
m_beginBottomRightPoint = m_beginToParentTransform.map(m_rotationController.formEditorItem()->qmlItemNode().instanceBoundingRect().bottomRight());
|
||||
|
||||
QmlAnchors anchors(m_rotationController.formEditorItem()->qmlItemNode().anchors());
|
||||
m_beginTopMargin = anchors.instanceMargin(AnchorLineTop);
|
||||
m_beginLeftMargin = anchors.instanceMargin(AnchorLineLeft);
|
||||
m_beginRightMargin = anchors.instanceMargin(AnchorLineRight);
|
||||
m_beginBottomMargin = anchors.instanceMargin(AnchorLineBottom);
|
||||
|
||||
m_beginRotation = m_rotationController.formEditorItem()->qmlItemNode().rotation();
|
||||
deleteSnapLines();
|
||||
}
|
||||
}
|
||||
|
||||
void RotationManipulator::update(const QPointF& updatePoint, Qt::KeyboardModifiers keyMods)
|
||||
{
|
||||
if (m_rotationController.isValid()) {
|
||||
FormEditorItem *formEditorItem = m_rotationController.formEditorItem();
|
||||
|
||||
const bool degreeStep5 = keyMods.testFlag(Qt::ShiftModifier);
|
||||
const bool degreeStep45 = keyMods.testFlag(Qt::AltModifier);
|
||||
|
||||
QPointF updatePointInLocalSpace = m_beginFromSceneToContentItemTransform.map(updatePoint);
|
||||
|
||||
QRectF boundingRect(m_beginBoundingRect);
|
||||
|
||||
QPointF transformOrigin;
|
||||
QVariant transformOriginVar = formEditorItem->qmlItemNode().transformOrigin();
|
||||
if (transformOriginVar.isValid()) {
|
||||
QmlDesigner::Enumeration a = transformOriginVar.value<QmlDesigner::Enumeration>();
|
||||
const QString originStr = a.nameToString();
|
||||
if (originStr == "TopLeft") {
|
||||
transformOrigin = boundingRect.topLeft();
|
||||
}
|
||||
else if (originStr == "Top") {
|
||||
transformOrigin.setX(boundingRect.center().x());
|
||||
transformOrigin.setY(boundingRect.top());
|
||||
}
|
||||
else if (originStr == "TopRight") {
|
||||
transformOrigin = boundingRect.topRight();
|
||||
}
|
||||
else if (originStr == "Right") {
|
||||
transformOrigin.setX(boundingRect.right());
|
||||
transformOrigin.setY(boundingRect.center().y());
|
||||
}
|
||||
else if (originStr == "BottomRight") {
|
||||
transformOrigin = boundingRect.bottomRight();
|
||||
}
|
||||
else if (originStr == "Bottom") {
|
||||
transformOrigin.setX(boundingRect.center().x());
|
||||
transformOrigin.setY(boundingRect.bottom());
|
||||
}
|
||||
else if (originStr == "BottomLeft") {
|
||||
transformOrigin = boundingRect.bottomLeft();
|
||||
}
|
||||
else if (originStr == "Left") {
|
||||
transformOrigin.setX(boundingRect.left());
|
||||
transformOrigin.setY(boundingRect.center().y());
|
||||
}
|
||||
else {
|
||||
//center and anything else
|
||||
transformOrigin = boundingRect.center();
|
||||
}
|
||||
}
|
||||
else {
|
||||
transformOrigin = boundingRect.center();
|
||||
}
|
||||
|
||||
auto angleCalc = [](const QPointF &origin, const QPointF &position){
|
||||
const qreal deltaX = origin.x() - position.x();
|
||||
const qreal deltaY = origin.y() - position.y();
|
||||
|
||||
return qRadiansToDegrees(qAtan2(deltaY, deltaX));
|
||||
};
|
||||
|
||||
auto snapCalc = [](const qreal angle, const qreal snap){
|
||||
return qRound(angle/snap)*snap;
|
||||
};
|
||||
|
||||
auto resultCalc = [&](qreal cursorAngle, qreal handleAngle) {
|
||||
qreal result = 0.0;
|
||||
const qreal rotateBy = cursorAngle - handleAngle;
|
||||
|
||||
if (degreeStep45)
|
||||
result = snapCalc(rotateBy, 45.0);
|
||||
else if (degreeStep5)
|
||||
result = snapCalc(rotateBy, 5.0);
|
||||
else
|
||||
result = rotateBy;
|
||||
|
||||
while (result > 360.)
|
||||
result -= 360.;
|
||||
while (result < -360.)
|
||||
result += 360.;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const qreal cursorAngle = angleCalc(transformOrigin, updatePointInLocalSpace);
|
||||
const QPointF topLeftHandle = boundingRect.topLeft();
|
||||
const QPointF topRightHandle = boundingRect.topRight();
|
||||
const QPointF bottomRightHandle = boundingRect.bottomRight();
|
||||
const QPointF bottomLeftHandle = boundingRect.bottomLeft();
|
||||
|
||||
if (m_rotationHandle->isTopLeftHandle()) {
|
||||
//we need to change origin coords, otherwise item will rotate unpredictably:
|
||||
if (transformOrigin == topLeftHandle)
|
||||
transformOrigin = boundingRect.center();
|
||||
|
||||
const qreal handleAngle = angleCalc(transformOrigin, topLeftHandle);
|
||||
formEditorItem->qmlItemNode().setRotation(resultCalc(cursorAngle + m_beginRotation, handleAngle));
|
||||
}
|
||||
else if (m_rotationHandle->isTopRightHandle()) {
|
||||
if (transformOrigin == topRightHandle)
|
||||
transformOrigin = boundingRect.center();
|
||||
const qreal handleAngle = angleCalc(transformOrigin, topRightHandle);
|
||||
formEditorItem->qmlItemNode().setRotation(resultCalc(cursorAngle + m_beginRotation, handleAngle));
|
||||
}
|
||||
else if (m_rotationHandle->isBottomRightHandle()) {
|
||||
if (transformOrigin == bottomRightHandle)
|
||||
transformOrigin = boundingRect.center();
|
||||
const qreal handleAngle = angleCalc(transformOrigin, bottomRightHandle);
|
||||
formEditorItem->qmlItemNode().setRotation(resultCalc(cursorAngle + m_beginRotation, handleAngle));
|
||||
}
|
||||
else if (m_rotationHandle->isBottomLeftHandle()) {
|
||||
if (transformOrigin == bottomLeftHandle)
|
||||
transformOrigin = boundingRect.center();
|
||||
const qreal handleAngle = angleCalc(transformOrigin, bottomLeftHandle);
|
||||
formEditorItem->qmlItemNode().setRotation(resultCalc(cursorAngle + m_beginRotation, handleAngle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RotationManipulator::end()
|
||||
{
|
||||
m_isActive = false;
|
||||
m_rewriterTransaction.commit();
|
||||
clear();
|
||||
removeHandle();
|
||||
}
|
||||
|
||||
void RotationManipulator::deleteSnapLines()
|
||||
{
|
||||
if (m_layerItem) {
|
||||
foreach (QGraphicsItem *item, m_graphicsLineList) {
|
||||
m_layerItem->scene()->removeItem(item);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
m_graphicsLineList.clear();
|
||||
m_view->scene()->update();
|
||||
}
|
||||
|
||||
RotationHandleItem *RotationManipulator::rotationHandle()
|
||||
{
|
||||
return m_rotationHandle;
|
||||
}
|
||||
|
||||
void RotationManipulator::clear()
|
||||
{
|
||||
m_rewriterTransaction.commit();
|
||||
|
||||
deleteSnapLines();
|
||||
m_beginBoundingRect = QRectF();
|
||||
m_beginFromSceneToContentItemTransform = QTransform();
|
||||
m_beginFromContentItemToSceneTransform = QTransform();
|
||||
m_beginFromItemToSceneTransform = QTransform();
|
||||
m_beginToParentTransform = QTransform();
|
||||
m_beginTopMargin = 0.0;
|
||||
m_beginLeftMargin = 0.0;
|
||||
m_beginRightMargin = 0.0;
|
||||
m_beginBottomMargin = 0.0;
|
||||
removeHandle();
|
||||
}
|
||||
|
||||
bool RotationManipulator::isActive() const
|
||||
{
|
||||
return m_isActive;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "rotationhandleitem.h"
|
||||
#include <snapper.h>
|
||||
#include "rewritertransaction.h"
|
||||
#include "formeditorview.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class RotationHandleItem;
|
||||
class Model;
|
||||
|
||||
class RotationManipulator
|
||||
{
|
||||
public:
|
||||
RotationManipulator(LayerItem *layerItem, FormEditorView *view);
|
||||
~RotationManipulator();
|
||||
|
||||
void setHandle(RotationHandleItem *rotationHandle);
|
||||
void removeHandle();
|
||||
|
||||
void begin(const QPointF& beginPoint);
|
||||
void update(const QPointF& updatePoint, Qt::KeyboardModifiers keyMods = Qt::NoModifier);
|
||||
void end();
|
||||
|
||||
void clear();
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
protected:
|
||||
void deleteSnapLines();
|
||||
RotationHandleItem *rotationHandle();
|
||||
|
||||
private:
|
||||
QPointer<FormEditorView> m_view;
|
||||
QList<QGraphicsItem*> m_graphicsLineList;
|
||||
RotationController m_rotationController; // hold the controller so that the handle cant be deleted
|
||||
QTransform m_beginFromSceneToContentItemTransform;
|
||||
QTransform m_beginFromContentItemToSceneTransform;
|
||||
QTransform m_beginFromItemToSceneTransform;
|
||||
QTransform m_beginToParentTransform;
|
||||
QRectF m_beginBoundingRect;
|
||||
QPointF m_beginBottomRightPoint;
|
||||
double m_beginTopMargin;
|
||||
double m_beginLeftMargin;
|
||||
double m_beginRightMargin;
|
||||
double m_beginBottomMargin;
|
||||
QPointer<LayerItem> m_layerItem;
|
||||
RotationHandleItem *m_rotationHandle = nullptr;
|
||||
RewriterTransaction m_rewriterTransaction;
|
||||
bool m_isActive = false;
|
||||
|
||||
qreal m_beginRotation;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
203
src/plugins/qmldesigner/components/formeditor/rotationtool.cpp
Normal file
203
src/plugins/qmldesigner/components/formeditor/rotationtool.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "rotationtool.h"
|
||||
|
||||
#include "formeditorscene.h"
|
||||
#include "formeditorview.h"
|
||||
#include "formeditorwidget.h"
|
||||
|
||||
#include "rotationhandleitem.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
RotationTool::RotationTool(FormEditorView *editorView)
|
||||
: AbstractFormEditorTool(editorView)
|
||||
, m_selectionIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_rotationIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_anchorIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_rotationManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
||||
{
|
||||
}
|
||||
|
||||
RotationTool::~RotationTool() = default;
|
||||
|
||||
|
||||
void RotationTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
|
||||
QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
if (itemList.isEmpty())
|
||||
return;
|
||||
|
||||
RotationHandleItem *rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||
if (rotationHandle && rotationHandle->rotationController().isValid()) {
|
||||
m_rotationManipulator.setHandle(rotationHandle);
|
||||
m_rotationManipulator.begin(event->scenePos());
|
||||
m_rotationIndicator.hide();
|
||||
m_anchorIndicator.hide();
|
||||
}
|
||||
}
|
||||
|
||||
AbstractFormEditorTool::mousePressEvent(itemList, event);
|
||||
}
|
||||
|
||||
void RotationTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
|
||||
QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_rotationManipulator.isActive())
|
||||
m_rotationManipulator.update(event->scenePos(), event->modifiers());
|
||||
}
|
||||
|
||||
void RotationTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||
QGraphicsSceneMouseEvent * /*event*/)
|
||||
{
|
||||
if (itemList.isEmpty()) {
|
||||
view()->changeToSelectionTool();
|
||||
return;
|
||||
}
|
||||
|
||||
RotationHandleItem* rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||
if (rotationHandle && rotationHandle->rotationController().isValid()) {
|
||||
m_rotationManipulator.setHandle(rotationHandle);
|
||||
} else {
|
||||
view()->changeToSelectionTool();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RotationTool::dragLeaveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RotationTool::dragMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RotationTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
||||
QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_rotationManipulator.isActive()) {
|
||||
if (itemList.isEmpty())
|
||||
return;
|
||||
|
||||
m_selectionIndicator.show();
|
||||
m_rotationIndicator.show();
|
||||
m_anchorIndicator.show();
|
||||
m_rotationManipulator.end();
|
||||
}
|
||||
|
||||
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
|
||||
}
|
||||
|
||||
void RotationTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> & /*itemList*/,
|
||||
QGraphicsSceneMouseEvent * /*event*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RotationTool::keyPressEvent(QKeyEvent * event)
|
||||
{
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Shift:
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_AltGr:
|
||||
event->setAccepted(false);
|
||||
return;
|
||||
}
|
||||
|
||||
double moveStep = 1.0;
|
||||
|
||||
if (event->modifiers().testFlag(Qt::ShiftModifier))
|
||||
moveStep = 10.0;
|
||||
}
|
||||
|
||||
void RotationTool::keyReleaseEvent(QKeyEvent * keyEvent)
|
||||
{
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_Shift:
|
||||
case Qt::Key_Alt:
|
||||
case Qt::Key_Control:
|
||||
case Qt::Key_AltGr:
|
||||
keyEvent->setAccepted(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RotationTool::itemsAboutToRemoved(const QList<FormEditorItem*> & /*itemList*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RotationTool::selectedItemsChanged(const QList<FormEditorItem*> & /*itemList*/)
|
||||
{
|
||||
m_selectionIndicator.setItems(items());
|
||||
m_rotationIndicator.setItems(items());
|
||||
m_anchorIndicator.setItems(items());
|
||||
}
|
||||
|
||||
void RotationTool::clear()
|
||||
{
|
||||
m_selectionIndicator.clear();
|
||||
m_rotationIndicator.clear();
|
||||
m_anchorIndicator.clear();
|
||||
m_rotationManipulator.clear();
|
||||
}
|
||||
|
||||
void RotationTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
const QList<FormEditorItem*> selectedItemList = filterSelectedModelNodes(itemList);
|
||||
|
||||
m_selectionIndicator.updateItems(selectedItemList);
|
||||
m_rotationIndicator.updateItems(selectedItemList);
|
||||
m_anchorIndicator.updateItems(selectedItemList);
|
||||
}
|
||||
|
||||
void RotationTool::instancesCompleted(const QList<FormEditorItem*> &/*itemList*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RotationTool::instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > & /*propertyList*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RotationTool::focusLost()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void RotationTool::instancesParentChanged(const QList<FormEditorItem *> &/*itemList*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} //namespace QmlDesigner
|
||||
75
src/plugins/qmldesigner/components/formeditor/rotationtool.h
Normal file
75
src/plugins/qmldesigner/components/formeditor/rotationtool.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "abstractformeditortool.h"
|
||||
#include "selectionindicator.h"
|
||||
#include "rotationindicator.h"
|
||||
#include "anchorindicator.h"
|
||||
#include "rotationmanipulator.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class RotationTool : public AbstractFormEditorTool
|
||||
{
|
||||
public:
|
||||
RotationTool(FormEditorView* editorView);
|
||||
~RotationTool() override;
|
||||
|
||||
void mousePressEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseMoveEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void hoverMoveEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void dragLeaveEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneDragDropEvent *event) override;
|
||||
void dragMoveEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneDragDropEvent *event) override;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent *keyEvent) override;
|
||||
|
||||
void itemsAboutToRemoved(const QList<FormEditorItem*> &itemList) override;
|
||||
|
||||
void selectedItemsChanged(const QList<FormEditorItem*> &itemList) override;
|
||||
|
||||
void clear() override;
|
||||
|
||||
void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) override;
|
||||
void instancesParentChanged(const QList<FormEditorItem *> &itemList) override;
|
||||
|
||||
void instancesCompleted(const QList<FormEditorItem*> &itemList) override;
|
||||
void instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
||||
|
||||
void focusLost() override;
|
||||
|
||||
private:
|
||||
SelectionIndicator m_selectionIndicator;
|
||||
RotationIndicator m_rotationIndicator;
|
||||
AnchorIndicator m_anchorIndicator;
|
||||
RotationManipulator m_rotationManipulator;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "formeditorgraphicsview.h"
|
||||
|
||||
#include "resizehandleitem.h"
|
||||
#include "rotationhandleitem.h"
|
||||
|
||||
#include <nodemetainfo.h>
|
||||
|
||||
@@ -42,14 +43,15 @@ const int s_startDragDistance = 20;
|
||||
const int s_startDragTime = 50;
|
||||
|
||||
SelectionTool::SelectionTool(FormEditorView *editorView)
|
||||
: AbstractFormEditorTool(editorView),
|
||||
m_rubberbandSelectionManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
|
||||
m_singleSelectionManipulator(editorView),
|
||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||
m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
: AbstractFormEditorTool(editorView)
|
||||
, m_rubberbandSelectionManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
||||
, m_singleSelectionManipulator(editorView)
|
||||
, m_selectionIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_resizeIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_rotationIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_anchorIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_bindingIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
, m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
||||
{
|
||||
m_selectionIndicator.setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
@@ -135,6 +137,12 @@ void SelectionTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||
return;
|
||||
}
|
||||
|
||||
RotationHandleItem* rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||
if (rotationHandle) {
|
||||
view()->changeToRotationTool();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((topSelectedItemIsMovable(itemList) && !view()->hasSingleSelectedModelNode())
|
||||
|| (selectedItemCursorInMovableArea(event->scenePos())
|
||||
&& !event->modifiers().testFlag(Qt::ControlModifier)
|
||||
@@ -245,6 +253,7 @@ void SelectionTool::clear()
|
||||
m_singleSelectionManipulator.clear();
|
||||
m_selectionIndicator.clear();
|
||||
m_resizeIndicator.clear();
|
||||
m_rotationIndicator.clear();
|
||||
m_anchorIndicator.clear();
|
||||
m_bindingIndicator.clear();
|
||||
m_contentNotEditableIndicator.clear();
|
||||
@@ -256,6 +265,7 @@ void SelectionTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
m_selectionIndicator.setItems(itemList);
|
||||
m_resizeIndicator.setItems(itemList);
|
||||
m_rotationIndicator.setItems(itemList);
|
||||
m_anchorIndicator.setItems(itemList);
|
||||
m_bindingIndicator.setItems(itemList);
|
||||
}
|
||||
@@ -266,6 +276,7 @@ void SelectionTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemLis
|
||||
|
||||
m_selectionIndicator.updateItems(selectedItemList);
|
||||
m_resizeIndicator.updateItems(selectedItemList);
|
||||
m_rotationIndicator.updateItems(selectedItemList);
|
||||
m_anchorIndicator.updateItems(selectedItemList);
|
||||
m_bindingIndicator.updateItems(selectedItemList);
|
||||
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "singleselectionmanipulator.h"
|
||||
#include "selectionindicator.h"
|
||||
#include "resizeindicator.h"
|
||||
#include "rotationindicator.h"
|
||||
#include "anchorindicator.h"
|
||||
#include "bindingindicator.h"
|
||||
#include "contentnoteditableindicator.h"
|
||||
@@ -85,6 +86,7 @@ private:
|
||||
SingleSelectionManipulator m_singleSelectionManipulator;
|
||||
SelectionIndicator m_selectionIndicator;
|
||||
ResizeIndicator m_resizeIndicator;
|
||||
RotationIndicator m_rotationIndicator;
|
||||
AnchorIndicator m_anchorIndicator;
|
||||
BindingIndicator m_bindingIndicator;
|
||||
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
|
||||
bool modelIsMovable() const;
|
||||
bool modelIsResizable() const;
|
||||
bool modelIsRotatable() const;
|
||||
bool modelIsInLayout() const;
|
||||
|
||||
QRectF instanceBoundingRect() const;
|
||||
@@ -123,6 +124,10 @@ public:
|
||||
bool isInLayout() const;
|
||||
bool canBereparentedTo(const ModelNode &potentialParent) const;
|
||||
|
||||
void setRotation(const qreal &angle);
|
||||
qreal rotation() const;
|
||||
QVariant transformOrigin();
|
||||
|
||||
bool isInStackedContainer() const;
|
||||
|
||||
bool isFlowView() const;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "rewriterview.h"
|
||||
#include "modelmerger.h"
|
||||
#include "rewritingexception.h"
|
||||
#include "designermcumanager.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QPlainTextEdit>
|
||||
@@ -286,6 +287,38 @@ bool QmlItemNode::modelIsResizable() const
|
||||
&& !modelIsInLayout();
|
||||
}
|
||||
|
||||
static bool isMcuRotationAllowed(QString itemName, bool hasChildren) {
|
||||
const QString propName = "rotation";
|
||||
const DesignerMcuManager &manager = DesignerMcuManager::instance();
|
||||
if (manager.isMCUProject()) {
|
||||
if (manager.allowedItemProperties().contains(itemName)) {
|
||||
const DesignerMcuManager::ItemProperties properties =
|
||||
manager.allowedItemProperties().value(itemName);
|
||||
if (properties.properties.contains(propName)) {
|
||||
if (hasChildren)
|
||||
return properties.allowChildren;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (manager.bannedItems().contains(itemName))
|
||||
return false;
|
||||
|
||||
if (manager.bannedProperties().contains(propName))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QmlItemNode::modelIsRotatable() const
|
||||
{
|
||||
return !modelNode().hasBindingProperty("rotation")
|
||||
&& itemIsResizable(modelNode())
|
||||
&& !modelIsInLayout()
|
||||
&& isMcuRotationAllowed(QString::fromUtf8(modelNode().type()), hasChildren());
|
||||
}
|
||||
|
||||
bool QmlItemNode::modelIsInLayout() const
|
||||
{
|
||||
if (modelNode().hasParentProperty()) {
|
||||
@@ -535,6 +568,30 @@ void QmlItemNode::setSize(const QSizeF &size)
|
||||
setVariantProperty("height", qRound(size.height()));
|
||||
}
|
||||
|
||||
void QmlItemNode::setRotation(const qreal &angle)
|
||||
{
|
||||
if (!hasBindingProperty("rotation"))
|
||||
setVariantProperty("rotation", angle);
|
||||
}
|
||||
|
||||
qreal QmlItemNode::rotation() const
|
||||
{
|
||||
if (hasProperty("rotation") && !hasBindingProperty("rotation")) {
|
||||
return modelNode().variantProperty("rotation").value().toReal();
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
QVariant QmlItemNode::transformOrigin()
|
||||
{
|
||||
if (hasProperty("transformOrigin")) {
|
||||
return modelNode().variantProperty("transformOrigin").value();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QmlFlowItemNode::isValid() const
|
||||
{
|
||||
return isValidQmlFlowItemNode(modelNode());
|
||||
|
||||
@@ -548,6 +548,16 @@ Project {
|
||||
"formeditor/resizemanipulator.h",
|
||||
"formeditor/resizetool.cpp",
|
||||
"formeditor/resizetool.h",
|
||||
"formeditor/rotationtool.cpp",
|
||||
"formeditor/rotationtool.h",
|
||||
"formeditor/rotationindicator.cpp",
|
||||
"formeditor/rotationindicator.h",
|
||||
"formeditor/rotationcontroller.cpp",
|
||||
"formeditor/rotationcontroller.h",
|
||||
"formeditor/rotationhandleitem.cpp",
|
||||
"formeditor/rotationhandleitem.h",
|
||||
"formeditor/rotationmanipulator.cpp",
|
||||
"formeditor/rotationmanipulator.h",
|
||||
"formeditor/rubberbandselectionmanipulator.cpp",
|
||||
"formeditor/rubberbandselectionmanipulator.h",
|
||||
"formeditor/scaleitem.cpp",
|
||||
|
||||
Reference in New Issue
Block a user