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
|
resizeindicator.cpp resizeindicator.h
|
||||||
resizemanipulator.cpp resizemanipulator.h
|
resizemanipulator.cpp resizemanipulator.h
|
||||||
resizetool.cpp resizetool.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
|
rubberbandselectionmanipulator.cpp rubberbandselectionmanipulator.h
|
||||||
scaleitem.cpp scaleitem.h
|
scaleitem.cpp scaleitem.h
|
||||||
scalemanipulator.cpp scalemanipulator.h
|
scalemanipulator.cpp scalemanipulator.h
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ SOURCES += formeditoritem.cpp \
|
|||||||
scaleitem.cpp \
|
scaleitem.cpp \
|
||||||
resizecontroller.cpp \
|
resizecontroller.cpp \
|
||||||
resizehandleitem.cpp \
|
resizehandleitem.cpp \
|
||||||
|
rotationtool.cpp \
|
||||||
|
rotationindicator.cpp \
|
||||||
|
rotationcontroller.cpp \
|
||||||
|
rotationhandleitem.cpp \
|
||||||
|
rotationmanipulator.cpp \
|
||||||
dragtool.cpp \
|
dragtool.cpp \
|
||||||
toolbox.cpp \
|
toolbox.cpp \
|
||||||
formeditorgraphicsview.cpp \
|
formeditorgraphicsview.cpp \
|
||||||
@@ -64,6 +69,11 @@ HEADERS += formeditorscene.h \
|
|||||||
scaleitem.h \
|
scaleitem.h \
|
||||||
resizecontroller.h \
|
resizecontroller.h \
|
||||||
resizehandleitem.h \
|
resizehandleitem.h \
|
||||||
|
rotationtool.h \
|
||||||
|
rotationindicator.h \
|
||||||
|
rotationcontroller.h \
|
||||||
|
rotationhandleitem.h \
|
||||||
|
rotationmanipulator.h \
|
||||||
dragtool.h \
|
dragtool.h \
|
||||||
toolbox.h \
|
toolbox.h \
|
||||||
formeditorgraphicsview.h \
|
formeditorgraphicsview.h \
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "formeditorview.h"
|
#include "formeditorview.h"
|
||||||
#include "nodeinstanceview.h"
|
#include "nodeinstanceview.h"
|
||||||
#include "selectiontool.h"
|
#include "selectiontool.h"
|
||||||
|
#include "rotationtool.h"
|
||||||
#include "movetool.h"
|
#include "movetool.h"
|
||||||
#include "resizetool.h"
|
#include "resizetool.h"
|
||||||
#include "dragtool.h"
|
#include "dragtool.h"
|
||||||
@@ -207,6 +208,7 @@ void FormEditorView::createFormEditorWidget()
|
|||||||
|
|
||||||
m_moveTool = std::make_unique<MoveTool>(this);
|
m_moveTool = std::make_unique<MoveTool>(this);
|
||||||
m_selectionTool = std::make_unique<SelectionTool>(this);
|
m_selectionTool = std::make_unique<SelectionTool>(this);
|
||||||
|
m_rotationTool = std::make_unique<RotationTool>(this);
|
||||||
m_resizeTool = std::make_unique<ResizeTool>(this);
|
m_resizeTool = std::make_unique<ResizeTool>(this);
|
||||||
m_dragTool = std::make_unique<DragTool>(this);
|
m_dragTool = std::make_unique<DragTool>(this);
|
||||||
|
|
||||||
@@ -248,6 +250,7 @@ void FormEditorView::cleanupToolsAndScene()
|
|||||||
{
|
{
|
||||||
m_currentTool->setItems(QList<FormEditorItem *>());
|
m_currentTool->setItems(QList<FormEditorItem *>());
|
||||||
m_selectionTool->clear();
|
m_selectionTool->clear();
|
||||||
|
m_rotationTool->clear();
|
||||||
m_moveTool->clear();
|
m_moveTool->clear();
|
||||||
m_resizeTool->clear();
|
m_resizeTool->clear();
|
||||||
m_dragTool->clear();
|
m_dragTool->clear();
|
||||||
@@ -548,6 +551,12 @@ void FormEditorView::resetToSelectionTool()
|
|||||||
changeCurrentToolTo(m_selectionTool.get());
|
changeCurrentToolTo(m_selectionTool.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorView::changeToRotationTool() {
|
||||||
|
if (m_currentTool == m_rotationTool.get())
|
||||||
|
return;
|
||||||
|
changeCurrentToolTo(m_rotationTool.get());
|
||||||
|
}
|
||||||
|
|
||||||
void FormEditorView::changeToResizeTool()
|
void FormEditorView::changeToResizeTool()
|
||||||
{
|
{
|
||||||
if (m_currentTool == m_resizeTool.get())
|
if (m_currentTool == m_resizeTool.get())
|
||||||
@@ -559,6 +568,7 @@ void FormEditorView::changeToTransformTools()
|
|||||||
{
|
{
|
||||||
if (m_currentTool == m_moveTool.get() ||
|
if (m_currentTool == m_moveTool.get() ||
|
||||||
m_currentTool == m_resizeTool.get() ||
|
m_currentTool == m_resizeTool.get() ||
|
||||||
|
m_currentTool == m_rotationTool.get() ||
|
||||||
m_currentTool == m_selectionTool.get())
|
m_currentTool == m_selectionTool.get())
|
||||||
return;
|
return;
|
||||||
changeToSelectionTool();
|
changeToSelectionTool();
|
||||||
@@ -854,6 +864,7 @@ void FormEditorView::reset()
|
|||||||
void FormEditorView::delayedReset()
|
void FormEditorView::delayedReset()
|
||||||
{
|
{
|
||||||
m_selectionTool->clear();
|
m_selectionTool->clear();
|
||||||
|
m_rotationTool->clear();
|
||||||
m_moveTool->clear();
|
m_moveTool->clear();
|
||||||
m_resizeTool->clear();
|
m_resizeTool->clear();
|
||||||
m_dragTool->clear();
|
m_dragTool->clear();
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class AbstractFormEditorTool;
|
|||||||
class AbstractCustomTool;
|
class AbstractCustomTool;
|
||||||
class MoveTool;
|
class MoveTool;
|
||||||
class SelectionTool;
|
class SelectionTool;
|
||||||
|
class RotationTool;
|
||||||
class ResizeTool;
|
class ResizeTool;
|
||||||
class DragTool;
|
class DragTool;
|
||||||
class ItemLibraryEntry;
|
class ItemLibraryEntry;
|
||||||
@@ -104,6 +105,7 @@ public:
|
|||||||
void changeToSelectionTool();
|
void changeToSelectionTool();
|
||||||
void changeToSelectionTool(QGraphicsSceneMouseEvent *event);
|
void changeToSelectionTool(QGraphicsSceneMouseEvent *event);
|
||||||
void resetToSelectionTool();
|
void resetToSelectionTool();
|
||||||
|
void changeToRotationTool();
|
||||||
void changeToResizeTool();
|
void changeToResizeTool();
|
||||||
void changeToTransformTools();
|
void changeToTransformTools();
|
||||||
void changeToCustomTool();
|
void changeToCustomTool();
|
||||||
@@ -152,6 +154,7 @@ private:
|
|||||||
QList<AbstractCustomTool*> m_customToolList;
|
QList<AbstractCustomTool*> m_customToolList;
|
||||||
std::unique_ptr<MoveTool> m_moveTool;
|
std::unique_ptr<MoveTool> m_moveTool;
|
||||||
std::unique_ptr<SelectionTool> m_selectionTool;
|
std::unique_ptr<SelectionTool> m_selectionTool;
|
||||||
|
std::unique_ptr<RotationTool> m_rotationTool;
|
||||||
std::unique_ptr<ResizeTool> m_resizeTool;
|
std::unique_ptr<ResizeTool> m_resizeTool;
|
||||||
std::unique_ptr<DragTool> m_dragTool;
|
std::unique_ptr<DragTool> m_dragTool;
|
||||||
AbstractFormEditorTool *m_currentTool = nullptr;
|
AbstractFormEditorTool *m_currentTool = nullptr;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "formeditorgraphicsview.h"
|
#include "formeditorgraphicsview.h"
|
||||||
|
|
||||||
#include "resizehandleitem.h"
|
#include "resizehandleitem.h"
|
||||||
|
#include "rotationhandleitem.h"
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ MoveTool::MoveTool(FormEditorView *editorView)
|
|||||||
m_moveManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
|
m_moveManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
|
||||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||||
|
m_rotationIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||||
m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
|
m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
|
||||||
m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
@@ -61,6 +63,7 @@ void MoveTool::clear()
|
|||||||
m_movingItems.clear();
|
m_movingItems.clear();
|
||||||
m_selectionIndicator.clear();
|
m_selectionIndicator.clear();
|
||||||
m_resizeIndicator.clear();
|
m_resizeIndicator.clear();
|
||||||
|
m_rotationIndicator.clear();
|
||||||
m_anchorIndicator.clear();
|
m_anchorIndicator.clear();
|
||||||
m_bindingIndicator.clear();
|
m_bindingIndicator.clear();
|
||||||
m_contentNotEditableIndicator.clear();
|
m_contentNotEditableIndicator.clear();
|
||||||
@@ -100,6 +103,7 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
|
|
||||||
m_selectionIndicator.hide();
|
m_selectionIndicator.hide();
|
||||||
m_resizeIndicator.hide();
|
m_resizeIndicator.hide();
|
||||||
|
m_rotationIndicator.hide();
|
||||||
m_anchorIndicator.hide();
|
m_anchorIndicator.hide();
|
||||||
m_bindingIndicator.hide();
|
m_bindingIndicator.hide();
|
||||||
|
|
||||||
@@ -135,6 +139,12 @@ void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RotationHandleItem* rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||||
|
if (rotationHandle) {
|
||||||
|
view()->changeToRotationTool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (view()->hasSingleSelectedModelNode() && selectedItemCursorInMovableArea(event->scenePos()))
|
if (view()->hasSingleSelectedModelNode() && selectedItemCursorInMovableArea(event->scenePos()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -182,6 +192,7 @@ void MoveTool::keyPressEvent(QKeyEvent *event)
|
|||||||
m_moveManipulator.setItems(movableItems);
|
m_moveManipulator.setItems(movableItems);
|
||||||
// m_selectionIndicator.hide();
|
// m_selectionIndicator.hide();
|
||||||
m_resizeIndicator.hide();
|
m_resizeIndicator.hide();
|
||||||
|
m_rotationIndicator.hide();
|
||||||
m_anchorIndicator.hide();
|
m_anchorIndicator.hide();
|
||||||
m_bindingIndicator.hide();
|
m_bindingIndicator.hide();
|
||||||
m_moveManipulator.beginRewriterTransaction();
|
m_moveManipulator.beginRewriterTransaction();
|
||||||
@@ -215,6 +226,7 @@ void MoveTool::keyReleaseEvent(QKeyEvent *keyEvent)
|
|||||||
m_moveManipulator.clear();
|
m_moveManipulator.clear();
|
||||||
// m_selectionIndicator.show();
|
// m_selectionIndicator.show();
|
||||||
m_resizeIndicator.show();
|
m_resizeIndicator.show();
|
||||||
|
m_rotationIndicator.show();
|
||||||
m_anchorIndicator.show();
|
m_anchorIndicator.show();
|
||||||
m_bindingIndicator.show();
|
m_bindingIndicator.show();
|
||||||
}
|
}
|
||||||
@@ -241,6 +253,7 @@ void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
|
|
||||||
m_selectionIndicator.show();
|
m_selectionIndicator.show();
|
||||||
m_resizeIndicator.show();
|
m_resizeIndicator.show();
|
||||||
|
m_rotationIndicator.show();
|
||||||
m_anchorIndicator.show();
|
m_anchorIndicator.show();
|
||||||
m_bindingIndicator.show();
|
m_bindingIndicator.show();
|
||||||
m_movingItems.clear();
|
m_movingItems.clear();
|
||||||
@@ -266,6 +279,7 @@ void MoveTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
|||||||
{
|
{
|
||||||
m_selectionIndicator.setItems(movingItems(itemList));
|
m_selectionIndicator.setItems(movingItems(itemList));
|
||||||
m_resizeIndicator.setItems(itemList);
|
m_resizeIndicator.setItems(itemList);
|
||||||
|
m_rotationIndicator.setItems(itemList);
|
||||||
m_anchorIndicator.setItems(itemList);
|
m_anchorIndicator.setItems(itemList);
|
||||||
m_bindingIndicator.setItems(itemList);
|
m_bindingIndicator.setItems(itemList);
|
||||||
updateMoveManipulator();
|
updateMoveManipulator();
|
||||||
@@ -386,6 +400,7 @@ void MoveTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
|
|||||||
|
|
||||||
m_selectionIndicator.updateItems(selectedItemList);
|
m_selectionIndicator.updateItems(selectedItemList);
|
||||||
m_resizeIndicator.updateItems(selectedItemList);
|
m_resizeIndicator.updateItems(selectedItemList);
|
||||||
|
m_rotationIndicator.updateItems(selectedItemList);
|
||||||
m_anchorIndicator.updateItems(selectedItemList);
|
m_anchorIndicator.updateItems(selectedItemList);
|
||||||
m_bindingIndicator.updateItems(selectedItemList);
|
m_bindingIndicator.updateItems(selectedItemList);
|
||||||
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "movemanipulator.h"
|
#include "movemanipulator.h"
|
||||||
#include "selectionindicator.h"
|
#include "selectionindicator.h"
|
||||||
#include "resizeindicator.h"
|
#include "resizeindicator.h"
|
||||||
|
#include "rotationindicator.h"
|
||||||
#include "anchorindicator.h"
|
#include "anchorindicator.h"
|
||||||
#include "bindingindicator.h"
|
#include "bindingindicator.h"
|
||||||
#include "contentnoteditableindicator.h"
|
#include "contentnoteditableindicator.h"
|
||||||
@@ -84,6 +85,7 @@ private:
|
|||||||
MoveManipulator m_moveManipulator;
|
MoveManipulator m_moveManipulator;
|
||||||
SelectionIndicator m_selectionIndicator;
|
SelectionIndicator m_selectionIndicator;
|
||||||
ResizeIndicator m_resizeIndicator;
|
ResizeIndicator m_resizeIndicator;
|
||||||
|
RotationIndicator m_rotationIndicator;
|
||||||
AnchorIndicator m_anchorIndicator;
|
AnchorIndicator m_anchorIndicator;
|
||||||
BindingIndicator m_bindingIndicator;
|
BindingIndicator m_bindingIndicator;
|
||||||
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ void ResizeIndicator::clear()
|
|||||||
m_itemControllerHash.clear();
|
m_itemControllerHash.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool itemIsResizable(const QmlItemNode &qmlItemNode)
|
static bool itemIsResizable(const QmlItemNode &qmlItemNode)
|
||||||
{
|
{
|
||||||
return qmlItemNode.isValid()
|
return qmlItemNode.isValid()
|
||||||
&& qmlItemNode.instanceIsResizable()
|
&& qmlItemNode.instanceIsResizable()
|
||||||
|
|||||||
@@ -38,11 +38,12 @@
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
ResizeTool::ResizeTool(FormEditorView *editorView)
|
ResizeTool::ResizeTool(FormEditorView *editorView)
|
||||||
: AbstractFormEditorTool(editorView),
|
: AbstractFormEditorTool(editorView)
|
||||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_selectionIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_resizeIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_anchorIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_resizeManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
, 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_resizeManipulator.begin(event->scenePos());
|
||||||
m_resizeIndicator.hide();
|
m_resizeIndicator.hide();
|
||||||
m_anchorIndicator.hide();
|
m_anchorIndicator.hide();
|
||||||
|
m_rotationIndicator.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +115,7 @@ void ResizeTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
m_selectionIndicator.show();
|
m_selectionIndicator.show();
|
||||||
m_resizeIndicator.show();
|
m_resizeIndicator.show();
|
||||||
m_anchorIndicator.show();
|
m_anchorIndicator.show();
|
||||||
|
m_rotationIndicator.show();
|
||||||
m_resizeManipulator.end(generateUseSnapping(event->modifiers()));
|
m_resizeManipulator.end(generateUseSnapping(event->modifiers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +174,7 @@ void ResizeTool::selectedItemsChanged(const QList<FormEditorItem*> & /*itemList*
|
|||||||
m_selectionIndicator.setItems(items());
|
m_selectionIndicator.setItems(items());
|
||||||
m_resizeIndicator.setItems(items());
|
m_resizeIndicator.setItems(items());
|
||||||
m_anchorIndicator.setItems(items());
|
m_anchorIndicator.setItems(items());
|
||||||
|
m_rotationIndicator.setItems(items());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeTool::clear()
|
void ResizeTool::clear()
|
||||||
@@ -178,6 +182,7 @@ void ResizeTool::clear()
|
|||||||
m_selectionIndicator.clear();
|
m_selectionIndicator.clear();
|
||||||
m_resizeIndicator.clear();
|
m_resizeIndicator.clear();
|
||||||
m_anchorIndicator.clear();
|
m_anchorIndicator.clear();
|
||||||
|
m_rotationIndicator.clear();
|
||||||
m_resizeManipulator.clear();
|
m_resizeManipulator.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +193,7 @@ void ResizeTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemList)
|
|||||||
m_selectionIndicator.updateItems(selectedItemList);
|
m_selectionIndicator.updateItems(selectedItemList);
|
||||||
m_resizeIndicator.updateItems(selectedItemList);
|
m_resizeIndicator.updateItems(selectedItemList);
|
||||||
m_anchorIndicator.updateItems(selectedItemList);
|
m_anchorIndicator.updateItems(selectedItemList);
|
||||||
|
m_rotationIndicator.updateItems(selectedItemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeTool::instancesCompleted(const QList<FormEditorItem*> &/*itemList*/)
|
void ResizeTool::instancesCompleted(const QList<FormEditorItem*> &/*itemList*/)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "selectionindicator.h"
|
#include "selectionindicator.h"
|
||||||
#include "resizeindicator.h"
|
#include "resizeindicator.h"
|
||||||
#include "anchorindicator.h"
|
#include "anchorindicator.h"
|
||||||
|
#include "rotationindicator.h"
|
||||||
#include "resizemanipulator.h"
|
#include "resizemanipulator.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -69,6 +70,7 @@ private:
|
|||||||
SelectionIndicator m_selectionIndicator;
|
SelectionIndicator m_selectionIndicator;
|
||||||
ResizeIndicator m_resizeIndicator;
|
ResizeIndicator m_resizeIndicator;
|
||||||
AnchorIndicator m_anchorIndicator;
|
AnchorIndicator m_anchorIndicator;
|
||||||
|
RotationIndicator m_rotationIndicator;
|
||||||
ResizeManipulator m_resizeManipulator;
|
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 "formeditorgraphicsview.h"
|
||||||
|
|
||||||
#include "resizehandleitem.h"
|
#include "resizehandleitem.h"
|
||||||
|
#include "rotationhandleitem.h"
|
||||||
|
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
@@ -42,14 +43,15 @@ const int s_startDragDistance = 20;
|
|||||||
const int s_startDragTime = 50;
|
const int s_startDragTime = 50;
|
||||||
|
|
||||||
SelectionTool::SelectionTool(FormEditorView *editorView)
|
SelectionTool::SelectionTool(FormEditorView *editorView)
|
||||||
: AbstractFormEditorTool(editorView),
|
: AbstractFormEditorTool(editorView)
|
||||||
m_rubberbandSelectionManipulator(editorView->scene()->manipulatorLayerItem(), editorView),
|
, m_rubberbandSelectionManipulator(editorView->scene()->manipulatorLayerItem(), editorView)
|
||||||
m_singleSelectionManipulator(editorView),
|
, m_singleSelectionManipulator(editorView)
|
||||||
m_selectionIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_selectionIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_resizeIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_resizeIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_anchorIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_rotationIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_bindingIndicator(editorView->scene()->manipulatorLayerItem()),
|
, m_anchorIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
, m_bindingIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
|
, m_contentNotEditableIndicator(editorView->scene()->manipulatorLayerItem())
|
||||||
{
|
{
|
||||||
m_selectionIndicator.setCursor(Qt::ArrowCursor);
|
m_selectionIndicator.setCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
@@ -135,6 +137,12 @@ void SelectionTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RotationHandleItem* rotationHandle = RotationHandleItem::fromGraphicsItem(itemList.constFirst());
|
||||||
|
if (rotationHandle) {
|
||||||
|
view()->changeToRotationTool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((topSelectedItemIsMovable(itemList) && !view()->hasSingleSelectedModelNode())
|
if ((topSelectedItemIsMovable(itemList) && !view()->hasSingleSelectedModelNode())
|
||||||
|| (selectedItemCursorInMovableArea(event->scenePos())
|
|| (selectedItemCursorInMovableArea(event->scenePos())
|
||||||
&& !event->modifiers().testFlag(Qt::ControlModifier)
|
&& !event->modifiers().testFlag(Qt::ControlModifier)
|
||||||
@@ -245,6 +253,7 @@ void SelectionTool::clear()
|
|||||||
m_singleSelectionManipulator.clear();
|
m_singleSelectionManipulator.clear();
|
||||||
m_selectionIndicator.clear();
|
m_selectionIndicator.clear();
|
||||||
m_resizeIndicator.clear();
|
m_resizeIndicator.clear();
|
||||||
|
m_rotationIndicator.clear();
|
||||||
m_anchorIndicator.clear();
|
m_anchorIndicator.clear();
|
||||||
m_bindingIndicator.clear();
|
m_bindingIndicator.clear();
|
||||||
m_contentNotEditableIndicator.clear();
|
m_contentNotEditableIndicator.clear();
|
||||||
@@ -256,6 +265,7 @@ void SelectionTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
|||||||
{
|
{
|
||||||
m_selectionIndicator.setItems(itemList);
|
m_selectionIndicator.setItems(itemList);
|
||||||
m_resizeIndicator.setItems(itemList);
|
m_resizeIndicator.setItems(itemList);
|
||||||
|
m_rotationIndicator.setItems(itemList);
|
||||||
m_anchorIndicator.setItems(itemList);
|
m_anchorIndicator.setItems(itemList);
|
||||||
m_bindingIndicator.setItems(itemList);
|
m_bindingIndicator.setItems(itemList);
|
||||||
}
|
}
|
||||||
@@ -266,6 +276,7 @@ void SelectionTool::formEditorItemsChanged(const QList<FormEditorItem*> &itemLis
|
|||||||
|
|
||||||
m_selectionIndicator.updateItems(selectedItemList);
|
m_selectionIndicator.updateItems(selectedItemList);
|
||||||
m_resizeIndicator.updateItems(selectedItemList);
|
m_resizeIndicator.updateItems(selectedItemList);
|
||||||
|
m_rotationIndicator.updateItems(selectedItemList);
|
||||||
m_anchorIndicator.updateItems(selectedItemList);
|
m_anchorIndicator.updateItems(selectedItemList);
|
||||||
m_bindingIndicator.updateItems(selectedItemList);
|
m_bindingIndicator.updateItems(selectedItemList);
|
||||||
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
m_contentNotEditableIndicator.updateItems(selectedItemList);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "singleselectionmanipulator.h"
|
#include "singleselectionmanipulator.h"
|
||||||
#include "selectionindicator.h"
|
#include "selectionindicator.h"
|
||||||
#include "resizeindicator.h"
|
#include "resizeindicator.h"
|
||||||
|
#include "rotationindicator.h"
|
||||||
#include "anchorindicator.h"
|
#include "anchorindicator.h"
|
||||||
#include "bindingindicator.h"
|
#include "bindingindicator.h"
|
||||||
#include "contentnoteditableindicator.h"
|
#include "contentnoteditableindicator.h"
|
||||||
@@ -85,6 +86,7 @@ private:
|
|||||||
SingleSelectionManipulator m_singleSelectionManipulator;
|
SingleSelectionManipulator m_singleSelectionManipulator;
|
||||||
SelectionIndicator m_selectionIndicator;
|
SelectionIndicator m_selectionIndicator;
|
||||||
ResizeIndicator m_resizeIndicator;
|
ResizeIndicator m_resizeIndicator;
|
||||||
|
RotationIndicator m_rotationIndicator;
|
||||||
AnchorIndicator m_anchorIndicator;
|
AnchorIndicator m_anchorIndicator;
|
||||||
BindingIndicator m_bindingIndicator;
|
BindingIndicator m_bindingIndicator;
|
||||||
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ public:
|
|||||||
|
|
||||||
bool modelIsMovable() const;
|
bool modelIsMovable() const;
|
||||||
bool modelIsResizable() const;
|
bool modelIsResizable() const;
|
||||||
|
bool modelIsRotatable() const;
|
||||||
bool modelIsInLayout() const;
|
bool modelIsInLayout() const;
|
||||||
|
|
||||||
QRectF instanceBoundingRect() const;
|
QRectF instanceBoundingRect() const;
|
||||||
@@ -123,6 +124,10 @@ public:
|
|||||||
bool isInLayout() const;
|
bool isInLayout() const;
|
||||||
bool canBereparentedTo(const ModelNode &potentialParent) const;
|
bool canBereparentedTo(const ModelNode &potentialParent) const;
|
||||||
|
|
||||||
|
void setRotation(const qreal &angle);
|
||||||
|
qreal rotation() const;
|
||||||
|
QVariant transformOrigin();
|
||||||
|
|
||||||
bool isInStackedContainer() const;
|
bool isInStackedContainer() const;
|
||||||
|
|
||||||
bool isFlowView() const;
|
bool isFlowView() const;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "rewriterview.h"
|
#include "rewriterview.h"
|
||||||
#include "modelmerger.h"
|
#include "modelmerger.h"
|
||||||
#include "rewritingexception.h"
|
#include "rewritingexception.h"
|
||||||
|
#include "designermcumanager.h"
|
||||||
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
@@ -286,6 +287,38 @@ bool QmlItemNode::modelIsResizable() const
|
|||||||
&& !modelIsInLayout();
|
&& !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
|
bool QmlItemNode::modelIsInLayout() const
|
||||||
{
|
{
|
||||||
if (modelNode().hasParentProperty()) {
|
if (modelNode().hasParentProperty()) {
|
||||||
@@ -535,6 +568,30 @@ void QmlItemNode::setSize(const QSizeF &size)
|
|||||||
setVariantProperty("height", qRound(size.height()));
|
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
|
bool QmlFlowItemNode::isValid() const
|
||||||
{
|
{
|
||||||
return isValidQmlFlowItemNode(modelNode());
|
return isValidQmlFlowItemNode(modelNode());
|
||||||
|
|||||||
@@ -548,6 +548,16 @@ Project {
|
|||||||
"formeditor/resizemanipulator.h",
|
"formeditor/resizemanipulator.h",
|
||||||
"formeditor/resizetool.cpp",
|
"formeditor/resizetool.cpp",
|
||||||
"formeditor/resizetool.h",
|
"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.cpp",
|
||||||
"formeditor/rubberbandselectionmanipulator.h",
|
"formeditor/rubberbandselectionmanipulator.h",
|
||||||
"formeditor/scaleitem.cpp",
|
"formeditor/scaleitem.cpp",
|
||||||
|
|||||||
Reference in New Issue
Block a user