forked from qt-creator/qt-creator
QmlDesigner: Support anchoring at snapping
Change-Id: I3ec504e931ee63761538acb4666a3c8ce1a592e5 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "abstractformeditortool.h"
|
#include "abstractformeditortool.h"
|
||||||
#include "formeditorview.h"
|
#include "formeditorview.h"
|
||||||
|
#include "formeditorwidget.h"
|
||||||
|
|
||||||
#include <modelnodecontextmenu.h>
|
#include <modelnodecontextmenu.h>
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
#include <QGraphicsSceneDragDropEvent>
|
#include <QGraphicsSceneDragDropEvent>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -219,6 +221,22 @@ void AbstractFormEditorTool::showContextMenu(QGraphicsSceneMouseEvent *event)
|
|||||||
ModelNodeContextMenu::showContextMenu(view(), event->screenPos(), event->scenePos().toPoint(), true);
|
ModelNodeContextMenu::showContextMenu(view(), event->screenPos(), event->scenePos().toPoint(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Snapper::Snapping AbstractFormEditorTool::generateUseSnapping(Qt::KeyboardModifiers keyboardModifier) const
|
||||||
|
{
|
||||||
|
bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
|
||||||
|
bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
|
||||||
|
|
||||||
|
Snapper::Snapping useSnapping = Snapper::NoSnapping;
|
||||||
|
if (keyboardModifier.testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
|
||||||
|
if (shouldSnappingAndAnchoring)
|
||||||
|
useSnapping = Snapper::UseSnappingAndAnchoring;
|
||||||
|
else
|
||||||
|
useSnapping = Snapper::UseSnapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
return useSnapping;
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractFormEditorTool::clear()
|
void AbstractFormEditorTool::clear()
|
||||||
{
|
{
|
||||||
m_itemList.clear();
|
m_itemList.clear();
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
#include <qmldesignercorelib_global.h>
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include "snapper.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QGraphicsItem;
|
class QGraphicsItem;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -99,6 +101,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void selectedItemsChanged(const QList<FormEditorItem*> &itemList) = 0;
|
virtual void selectedItemsChanged(const QList<FormEditorItem*> &itemList) = 0;
|
||||||
virtual void showContextMenu(QGraphicsSceneMouseEvent *event);
|
virtual void showContextMenu(QGraphicsSceneMouseEvent *event);
|
||||||
|
Snapper::Snapping generateUseSnapping(Qt::KeyboardModifiers keyboardModifier) const;
|
||||||
|
|
||||||
FormEditorView *view() const;
|
FormEditorView *view() const;
|
||||||
void setView(FormEditorView *view);
|
void setView(FormEditorView *view);
|
||||||
|
|||||||
@@ -275,8 +275,8 @@ void DragTool::dropEvent(QGraphicsSceneDragDropEvent * event)
|
|||||||
if (event->mimeData()->hasFormat("application/vnd.bauhaus.itemlibraryinfo") ||
|
if (event->mimeData()->hasFormat("application/vnd.bauhaus.itemlibraryinfo") ||
|
||||||
event->mimeData()->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
event->mimeData()->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
||||||
event->accept();
|
event->accept();
|
||||||
end(event->scenePos());
|
end(generateUseSnapping(event->modifiers()));
|
||||||
//Q_ASSERT(m_token.isValid());
|
|
||||||
try {
|
try {
|
||||||
m_rewriterTransaction.commit();
|
m_rewriterTransaction.commit();
|
||||||
} catch (RewritingException &e) {
|
} catch (RewritingException &e) {
|
||||||
@@ -333,7 +333,9 @@ void DragTool::dragLeaveEvent(QGraphicsSceneDragDropEvent * event)
|
|||||||
event->accept();
|
event->accept();
|
||||||
if (m_dragNode.isValid())
|
if (m_dragNode.isValid())
|
||||||
m_dragNode.destroy();
|
m_dragNode.destroy();
|
||||||
end(event->scenePos());
|
|
||||||
|
m_moveManipulator.end();
|
||||||
|
clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_rewriterTransaction.commit();
|
m_rewriterTransaction.commit();
|
||||||
@@ -367,7 +369,7 @@ void DragTool::dragMoveEvent(QGraphicsSceneDragDropEvent * event)
|
|||||||
|
|
||||||
FormEditorItem *parentItem = calculateContainer(event->scenePos() + QPoint(2, 2));
|
FormEditorItem *parentItem = calculateContainer(event->scenePos() + QPoint(2, 2));
|
||||||
if (!parentItem) { //if there is no parent any more - the use left the scene
|
if (!parentItem) { //if there is no parent any more - the use left the scene
|
||||||
end(event->scenePos());
|
end();
|
||||||
QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::show();
|
QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::show();
|
||||||
m_dragNode.destroy(); //delete the node then
|
m_dragNode.destroy(); //delete the node then
|
||||||
return;
|
return;
|
||||||
@@ -405,9 +407,15 @@ void DragTool::dragMoveEvent(QGraphicsSceneDragDropEvent * event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragTool::end(QPointF scenePos)
|
void DragTool::end()
|
||||||
{
|
{
|
||||||
m_moveManipulator.end(scenePos);
|
m_moveManipulator.end();
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DragTool::end(Snapper::Snapping useSnapping)
|
||||||
|
{
|
||||||
|
m_moveManipulator.end(useSnapping);
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +432,7 @@ void DragTool::move(QPointF scenePos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
|
//MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
|
||||||
MoveManipulator::Snapping useSnapping = MoveManipulator::UseSnapping;
|
Snapper::Snapping useSnapping = Snapper::UseSnapping;
|
||||||
/* if (event->modifiers().testFlag(Qt::ControlModifier) != view()->isSnapButtonChecked())
|
/* if (event->modifiers().testFlag(Qt::ControlModifier) != view()->isSnapButtonChecked())
|
||||||
useSnapping = MoveManipulator::UseSnapping;*/
|
useSnapping = MoveManipulator::UseSnapping;*/
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,8 @@ private:
|
|||||||
QList<Import> missingImportList(const ItemLibraryEntry &itemLibraryEntry);
|
QList<Import> missingImportList(const ItemLibraryEntry &itemLibraryEntry);
|
||||||
|
|
||||||
void begin(QPointF scenePos);
|
void begin(QPointF scenePos);
|
||||||
void end(QPointF scenePos);
|
void end();
|
||||||
|
void end(Snapper::Snapping useSnapping);
|
||||||
void move(QPointF scenePos);
|
void move(QPointF scenePos);
|
||||||
|
|
||||||
MoveManipulator m_moveManipulator;
|
MoveManipulator m_moveManipulator;
|
||||||
|
|||||||
@@ -60,17 +60,23 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
|||||||
|
|
||||||
m_toolActionGroup = new QActionGroup(this);
|
m_toolActionGroup = new QActionGroup(this);
|
||||||
|
|
||||||
m_transformToolAction = m_toolActionGroup->addAction(tr("Transform Tool (Q)."));
|
|
||||||
m_transformToolAction->setShortcut(Qt::Key_Q);
|
|
||||||
m_transformToolAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
||||||
m_transformToolAction->setCheckable(true);
|
|
||||||
m_transformToolAction->setChecked(true);
|
|
||||||
m_transformToolAction->setIcon(QPixmap(":/icon/tool/transform.png"));
|
|
||||||
connect(m_transformToolAction.data(), SIGNAL(triggered(bool)), SLOT(changeTransformTool(bool)));
|
|
||||||
|
|
||||||
|
|
||||||
QActionGroup *layoutActionGroup = new QActionGroup(this);
|
QActionGroup *layoutActionGroup = new QActionGroup(this);
|
||||||
layoutActionGroup->setExclusive(false);
|
layoutActionGroup->setExclusive(true);
|
||||||
|
|
||||||
|
m_noSnappingAction = layoutActionGroup->addAction(tr("No snapping (T)."));
|
||||||
|
m_noSnappingAction->setShortcut(Qt::Key_W);
|
||||||
|
m_noSnappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||||
|
m_noSnappingAction->setCheckable(true);
|
||||||
|
m_noSnappingAction->setChecked(true);
|
||||||
|
m_noSnappingAction->setIcon(QPixmap(":/icon/layout/no_snapping.png"));
|
||||||
|
|
||||||
|
m_snappingAndAnchoringAction = layoutActionGroup->addAction(tr("Snapping with anchoring (W)."));
|
||||||
|
m_snappingAndAnchoringAction->setShortcut(Qt::Key_W);
|
||||||
|
m_snappingAndAnchoringAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||||
|
m_snappingAndAnchoringAction->setCheckable(true);
|
||||||
|
m_snappingAndAnchoringAction->setChecked(true);
|
||||||
|
m_snappingAndAnchoringAction->setIcon(QPixmap(":/icon/layout/snapping_and_anchoring.png"));
|
||||||
|
|
||||||
m_snappingAction = layoutActionGroup->addAction(tr("Snap to guides (E)."));
|
m_snappingAction = layoutActionGroup->addAction(tr("Snap to guides (E)."));
|
||||||
m_snappingAction->setShortcut(Qt::Key_E);
|
m_snappingAction->setShortcut(Qt::Key_E);
|
||||||
m_snappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
m_snappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||||
@@ -78,14 +84,6 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
|||||||
m_snappingAction->setChecked(true);
|
m_snappingAction->setChecked(true);
|
||||||
m_snappingAction->setIcon(QPixmap(":/icon/layout/snapping.png"));
|
m_snappingAction->setIcon(QPixmap(":/icon/layout/snapping.png"));
|
||||||
|
|
||||||
m_snappingAndAnchoringAction = layoutActionGroup->addAction(tr("Toggle snapping and anchoring (R)."));
|
|
||||||
m_snappingAndAnchoringAction->setShortcut(Qt::Key_R);
|
|
||||||
m_snappingAndAnchoringAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
||||||
m_snappingAndAnchoringAction->setCheckable(true);
|
|
||||||
m_snappingAndAnchoringAction->setChecked(false);
|
|
||||||
m_snappingAndAnchoringAction->setEnabled(false);
|
|
||||||
m_snappingAndAnchoringAction->setVisible(false);
|
|
||||||
m_snappingAndAnchoringAction->setIcon(QPixmap(":/icon/layout/snapping_and_anchoring.png"));
|
|
||||||
|
|
||||||
addActions(layoutActionGroup->actions());
|
addActions(layoutActionGroup->actions());
|
||||||
upperActions.append(layoutActionGroup->actions());
|
upperActions.append(layoutActionGroup->actions());
|
||||||
@@ -125,8 +123,6 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
|||||||
addAction(m_rootHeightAction.data());
|
addAction(m_rootHeightAction.data());
|
||||||
upperActions.append(m_rootHeightAction.data());
|
upperActions.append(m_rootHeightAction.data());
|
||||||
|
|
||||||
m_snappingAndAnchoringAction = layoutActionGroup->addAction(tr("Toggle snapping and anchoring (R)."));
|
|
||||||
|
|
||||||
m_toolBox = new ToolBox(this);
|
m_toolBox = new ToolBox(this);
|
||||||
fillLayout->addWidget(m_toolBox.data());
|
fillLayout->addWidget(m_toolBox.data());
|
||||||
m_toolBox->setLeftSideActions(upperActions);
|
m_toolBox->setLeftSideActions(upperActions);
|
||||||
@@ -246,11 +242,6 @@ ZoomAction *FormEditorWidget::zoomAction() const
|
|||||||
return m_zoomAction.data();
|
return m_zoomAction.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *FormEditorWidget::transformToolAction() const
|
|
||||||
{
|
|
||||||
return m_transformToolAction.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction *FormEditorWidget::showBoundingRectAction() const
|
QAction *FormEditorWidget::showBoundingRectAction() const
|
||||||
{
|
{
|
||||||
return m_showBoundingRectAction.data();
|
return m_showBoundingRectAction.data();
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public:
|
|||||||
FormEditorWidget(FormEditorView *view);
|
FormEditorWidget(FormEditorView *view);
|
||||||
|
|
||||||
ZoomAction *zoomAction() const;
|
ZoomAction *zoomAction() const;
|
||||||
QAction *transformToolAction() const;
|
|
||||||
QAction *showBoundingRectAction() const;
|
QAction *showBoundingRectAction() const;
|
||||||
QAction *selectOnlyContentItemsAction() const;
|
QAction *selectOnlyContentItemsAction() const;
|
||||||
QAction *snappingAction() const;
|
QAction *snappingAction() const;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ void MoveManipulator::synchronizeParent(const QList<FormEditorItem*> &itemList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!parentNode.metaInfo().isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1))
|
if (!parentNode.metaInfo().isSubclassOf("<cpp>.QDeclarativeBasePositioner", -1, -1))
|
||||||
update(m_lastPosition, NoSnapping, UseBaseState);
|
update(m_lastPosition, Snapper::NoSnapping, UseBaseState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveManipulator::synchronizeInstanceParent(const QList<FormEditorItem*> &itemList)
|
void MoveManipulator::synchronizeInstanceParent(const QList<FormEditorItem*> &itemList)
|
||||||
@@ -260,7 +260,7 @@ QHash<FormEditorItem*, QRectF> MoveManipulator::tanslatedBoundingRects(const QHa
|
|||||||
/*
|
/*
|
||||||
/brief updates the position of the items.
|
/brief updates the position of the items.
|
||||||
*/
|
*/
|
||||||
void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, State stateToBeManipulated)
|
void MoveManipulator::update(const QPointF& updatePoint, Snapper::Snapping useSnapping, State stateToBeManipulated)
|
||||||
{
|
{
|
||||||
m_lastPosition = updatePoint;
|
m_lastPosition = updatePoint;
|
||||||
deleteSnapLines(); //Since they position is changed and the item is moved the snapping lines are
|
deleteSnapLines(); //Since they position is changed and the item is moved the snapping lines are
|
||||||
@@ -275,12 +275,7 @@ void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, S
|
|||||||
|
|
||||||
QPointF offsetVector(updatePointInContainerSpace - beginPointInContainerSpace);
|
QPointF offsetVector(updatePointInContainerSpace - beginPointInContainerSpace);
|
||||||
|
|
||||||
if (useSnapping == UseSnappingAndAnchoring)
|
if (useSnapping == Snapper::UseSnapping || useSnapping == Snapper::UseSnappingAndAnchoring) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useSnapping == UseSnapping || useSnapping == UseSnappingAndAnchoring) {
|
|
||||||
offsetVector -= findSnappingOffset(tanslatedBoundingRects(m_beginItemRectHash, offsetVector));
|
offsetVector -= findSnappingOffset(tanslatedBoundingRects(m_beginItemRectHash, offsetVector));
|
||||||
generateSnappingLines(tanslatedBoundingRects(m_beginItemRectHash, offsetVector));
|
generateSnappingLines(tanslatedBoundingRects(m_beginItemRectHash, offsetVector));
|
||||||
}
|
}
|
||||||
@@ -386,15 +381,25 @@ void MoveManipulator::reparentTo(FormEditorItem *newParent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MoveManipulator::end()
|
||||||
void MoveManipulator::end(const QPointF &/*endPoint*/)
|
|
||||||
{
|
{
|
||||||
m_isActive = false;
|
m_isActive = false;
|
||||||
deleteSnapLines();
|
deleteSnapLines();
|
||||||
// setOpacityForAllElements(1.0);
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MoveManipulator::end(Snapper::Snapping useSnapping)
|
||||||
|
{
|
||||||
|
if (useSnapping == Snapper::UseSnappingAndAnchoring) {
|
||||||
|
foreach (FormEditorItem *formEditorItem, m_itemList)
|
||||||
|
m_snapper.adjustAnchoringOfItem(formEditorItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
void MoveManipulator::moveBy(double deltaX, double deltaY)
|
void MoveManipulator::moveBy(double deltaX, double deltaY)
|
||||||
{
|
{
|
||||||
foreach (FormEditorItem* item, m_itemList) {
|
foreach (FormEditorItem* item, m_itemList) {
|
||||||
|
|||||||
@@ -49,12 +49,6 @@ class Model;
|
|||||||
class MoveManipulator
|
class MoveManipulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Snapping {
|
|
||||||
UseSnapping,
|
|
||||||
UseSnappingAndAnchoring,
|
|
||||||
NoSnapping
|
|
||||||
};
|
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
UseActualState,
|
UseActualState,
|
||||||
UseBaseState
|
UseBaseState
|
||||||
@@ -68,9 +62,10 @@ public:
|
|||||||
void synchronizeParent(const QList<FormEditorItem*> &itemList, const ModelNode &parentNode);
|
void synchronizeParent(const QList<FormEditorItem*> &itemList, const ModelNode &parentNode);
|
||||||
|
|
||||||
void begin(const QPointF& beginPoint);
|
void begin(const QPointF& beginPoint);
|
||||||
void update(const QPointF& updatePoint, Snapping useSnapping, State stateToBeManipulated = UseActualState);
|
void update(const QPointF& updatePoint, Snapper::Snapping useSnapping, State stateToBeManipulated = UseActualState);
|
||||||
void reparentTo(FormEditorItem *newParent);
|
void reparentTo(FormEditorItem *newParent);
|
||||||
void end(const QPointF& endPoint);
|
void end();
|
||||||
|
void end(Snapper::Snapping useSnapping);
|
||||||
|
|
||||||
void moveBy(double deltaX, double deltaY);
|
void moveBy(double deltaX, double deltaY);
|
||||||
|
|
||||||
@@ -101,6 +96,8 @@ protected:
|
|||||||
|
|
||||||
void setPosition(QmlItemNode itemNode, const QPointF &position);
|
void setPosition(QmlItemNode itemNode, const QPointF &position);
|
||||||
|
|
||||||
|
void adjustAnchoringOfItem(FormEditorItem *item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Snapper m_snapper;
|
Snapper m_snapper;
|
||||||
QWeakPointer<LayerItem> m_layerItem;
|
QWeakPointer<LayerItem> m_layerItem;
|
||||||
|
|||||||
@@ -103,18 +103,7 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
|
m_moveManipulator.update(event->scenePos(), generateUseSnapping(event->modifiers()));
|
||||||
bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
|
|
||||||
|
|
||||||
MoveManipulator::Snapping useSnapping = MoveManipulator::NoSnapping;
|
|
||||||
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
|
|
||||||
if (shouldSnappingAndAnchoring)
|
|
||||||
useSnapping = MoveManipulator::UseSnappingAndAnchoring;
|
|
||||||
else
|
|
||||||
useSnapping = MoveManipulator::UseSnapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_moveManipulator.update(event->scenePos(), useSnapping);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,26 +203,12 @@ void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
if (m_movingItems.isEmpty())
|
if (m_movingItems.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QLineF moveVector(event->scenePos(), m_moveManipulator.beginPoint());
|
m_moveManipulator.end(generateUseSnapping(event->modifiers()));
|
||||||
if (moveVector.length() < QApplication::startDragDistance())
|
|
||||||
{
|
|
||||||
QPointF beginPoint(m_moveManipulator.beginPoint());
|
|
||||||
|
|
||||||
m_moveManipulator.end(beginPoint);
|
|
||||||
|
|
||||||
// m_selectionIndicator.show();
|
|
||||||
m_resizeIndicator.show();
|
|
||||||
m_movingItems.clear();
|
|
||||||
|
|
||||||
view()->changeToSelectionTool(event);
|
|
||||||
} else {
|
|
||||||
m_moveManipulator.end(event->scenePos());
|
|
||||||
|
|
||||||
m_selectionIndicator.show();
|
m_selectionIndicator.show();
|
||||||
m_resizeIndicator.show();
|
m_resizeIndicator.show();
|
||||||
m_movingItems.clear();
|
m_movingItems.clear();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
|
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,14 +99,14 @@ void ResizeManipulator::begin(const QPointF &/*beginPoint*/)
|
|||||||
// return QSizeF(sizeAsPoint.x(), sizeAsPoint.y());
|
// return QSizeF(sizeAsPoint.x(), sizeAsPoint.y());
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping)
|
void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping useSnapping)
|
||||||
{
|
{
|
||||||
const double minimumWidth = 0.0;
|
const double minimumWidth = 0.0;
|
||||||
const double minimumHeight = 0.0;
|
const double minimumHeight = 0.0;
|
||||||
|
|
||||||
deleteSnapLines();
|
deleteSnapLines();
|
||||||
|
|
||||||
bool snap = useSnapping == UseSnapping || useSnapping == UseSnappingAndAnchoring;
|
bool snap = useSnapping == Snapper::UseSnapping || useSnapping == Snapper::UseSnappingAndAnchoring;
|
||||||
|
|
||||||
if (m_resizeController.isValid()) {
|
if (m_resizeController.isValid()) {
|
||||||
|
|
||||||
@@ -376,8 +376,15 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeManipulator::end()
|
void ResizeManipulator::end(Snapper::Snapping useSnapping)
|
||||||
{
|
{
|
||||||
|
if (useSnapping == Snapper::UseSnappingAndAnchoring) {
|
||||||
|
deleteSnapLines();
|
||||||
|
m_snapper.setTransformtionSpaceFormEditorItem(m_snapper.containerFormEditorItem());
|
||||||
|
m_snapper.updateSnappingLines(m_resizeController.formEditorItem());
|
||||||
|
m_snapper.adjustAnchoringOfItem(m_resizeController.formEditorItem());
|
||||||
|
}
|
||||||
|
|
||||||
m_isActive = false;
|
m_isActive = false;
|
||||||
m_rewriterTransaction.commit();
|
m_rewriterTransaction.commit();
|
||||||
clear();
|
clear();
|
||||||
|
|||||||
@@ -44,12 +44,6 @@ class Model;
|
|||||||
class ResizeManipulator
|
class ResizeManipulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Snapping {
|
|
||||||
UseSnapping,
|
|
||||||
UseSnappingAndAnchoring,
|
|
||||||
NoSnapping
|
|
||||||
};
|
|
||||||
|
|
||||||
ResizeManipulator(LayerItem *layerItem, FormEditorView *view);
|
ResizeManipulator(LayerItem *layerItem, FormEditorView *view);
|
||||||
~ResizeManipulator();
|
~ResizeManipulator();
|
||||||
|
|
||||||
@@ -57,8 +51,8 @@ public:
|
|||||||
void removeHandle();
|
void removeHandle();
|
||||||
|
|
||||||
void begin(const QPointF& beginPoint);
|
void begin(const QPointF& beginPoint);
|
||||||
void update(const QPointF& updatePoint, Snapping useSnapping);
|
void update(const QPointF& updatePoint, Snapper::Snapping useSnapping);
|
||||||
void end();
|
void end(Snapper::Snapping useSnapping);
|
||||||
|
|
||||||
void moveBy(double deltaX, double deltaY);
|
void moveBy(double deltaX, double deltaY);
|
||||||
|
|
||||||
|
|||||||
@@ -75,20 +75,8 @@ void ResizeTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
void ResizeTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
|
void ResizeTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
|
||||||
QGraphicsSceneMouseEvent *event)
|
QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (m_resizeManipulator.isActive()) {
|
if (m_resizeManipulator.isActive())
|
||||||
bool shouldSnapping = view()->formEditorWidget()->snappingAction()->isChecked();
|
m_resizeManipulator.update(event->scenePos(), generateUseSnapping(event->modifiers()));
|
||||||
bool shouldSnappingAndAnchoring = view()->formEditorWidget()->snappingAndAnchoringAction()->isChecked();
|
|
||||||
|
|
||||||
ResizeManipulator::Snapping useSnapping = ResizeManipulator::NoSnapping;
|
|
||||||
if (event->modifiers().testFlag(Qt::ControlModifier) != (shouldSnapping || shouldSnappingAndAnchoring)) {
|
|
||||||
if (shouldSnappingAndAnchoring)
|
|
||||||
useSnapping = ResizeManipulator::UseSnappingAndAnchoring;
|
|
||||||
else
|
|
||||||
useSnapping = ResizeManipulator::UseSnapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resizeManipulator.update(event->scenePos(), useSnapping);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
void ResizeTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
@@ -128,7 +116,7 @@ void ResizeTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
|||||||
|
|
||||||
m_selectionIndicator.show();
|
m_selectionIndicator.show();
|
||||||
m_resizeIndicator.show();
|
m_resizeIndicator.show();
|
||||||
m_resizeManipulator.end();
|
m_resizeManipulator.end(generateUseSnapping(event->modifiers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
|
AbstractFormEditorTool::mouseReleaseEvent(itemList, event);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <qmlanchors.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -525,11 +526,6 @@ static QList<QLineF> mergedHorizontalLines(const QList<QLineF> &lineList)
|
|||||||
return mergedLineList;
|
return mergedLineList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static QList<QLineF> mergedVerticalLines(const QList<QLineF> &lineList)
|
static QList<QLineF> mergedVerticalLines(const QList<QLineF> &lineList)
|
||||||
{
|
{
|
||||||
QList<QLineF> mergedLineList;
|
QList<QLineF> mergedLineList;
|
||||||
@@ -567,6 +563,155 @@ QList<QGraphicsItem*> Snapper::generateSnappingLines(const QRectF &boundingRect,
|
|||||||
return generateSnappingLines(boundingRectList, layerItem, transform);
|
return generateSnappingLines(boundingRectList, layerItem, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QmlItemNode findItemOnSnappingLine(const QmlItemNode &sourceQmlItemNode, const SnapLineMap &snappingLines, double anchorLine, AnchorLine::Type anchorLineType)
|
||||||
|
{
|
||||||
|
QmlItemNode targetQmlItemNode;
|
||||||
|
double targetAnchorLine = 0.0;
|
||||||
|
|
||||||
|
targetAnchorLine = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
AnchorLine::Type compareAnchorLineType;
|
||||||
|
|
||||||
|
if (anchorLineType == AnchorLine::Left
|
||||||
|
|| anchorLineType == AnchorLine::Right)
|
||||||
|
compareAnchorLineType = AnchorLine::Top;
|
||||||
|
else
|
||||||
|
compareAnchorLineType = AnchorLine::Left;
|
||||||
|
|
||||||
|
SnapLineMapIterator snapLineIterator(snappingLines);
|
||||||
|
while (snapLineIterator.hasNext()) {
|
||||||
|
snapLineIterator.next();
|
||||||
|
double snapLine = snapLineIterator.key();
|
||||||
|
|
||||||
|
if (qAbs(snapLine - anchorLine ) < 1.0) {
|
||||||
|
QmlItemNode possibleAchorItemNode = snapLineIterator.value().second->qmlItemNode();
|
||||||
|
|
||||||
|
double currentToAnchorLine = possibleAchorItemNode.anchors().instanceAnchorLine(compareAnchorLineType);
|
||||||
|
|
||||||
|
if (possibleAchorItemNode != sourceQmlItemNode) {
|
||||||
|
if (sourceQmlItemNode.instanceParent() == possibleAchorItemNode) {
|
||||||
|
targetQmlItemNode = possibleAchorItemNode;
|
||||||
|
targetAnchorLine = currentToAnchorLine;
|
||||||
|
break;
|
||||||
|
} else if (currentToAnchorLine < targetAnchorLine) {
|
||||||
|
targetQmlItemNode = possibleAchorItemNode;
|
||||||
|
targetAnchorLine = currentToAnchorLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetQmlItemNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adjustAnchorLine(const QmlItemNode &sourceQmlItemNode,
|
||||||
|
const QmlItemNode &containerQmlItemNode,
|
||||||
|
const SnapLineMap &snappingLines,
|
||||||
|
const SnapLineMap &snappingOffsets,
|
||||||
|
AnchorLine::Type lineAnchorLineType,
|
||||||
|
AnchorLine::Type offsetAnchorLineType)
|
||||||
|
{
|
||||||
|
QmlAnchors qmlAnchors = sourceQmlItemNode.anchors();
|
||||||
|
|
||||||
|
double fromAnchorLine = sourceQmlItemNode.anchors().instanceAnchorLine(lineAnchorLineType);
|
||||||
|
QmlItemNode targetQmlItemNode = findItemOnSnappingLine(sourceQmlItemNode, snappingLines, fromAnchorLine, lineAnchorLineType);
|
||||||
|
|
||||||
|
if (targetQmlItemNode.isValid() && !targetQmlItemNode.anchors().checkForCycle(lineAnchorLineType, sourceQmlItemNode)) {
|
||||||
|
double margin = 0.0;
|
||||||
|
|
||||||
|
if (targetQmlItemNode == containerQmlItemNode) {
|
||||||
|
if (lineAnchorLineType == AnchorLine::Left
|
||||||
|
|| lineAnchorLineType == AnchorLine::Top)
|
||||||
|
margin = fromAnchorLine;
|
||||||
|
else if (lineAnchorLineType == AnchorLine::Right)
|
||||||
|
margin = targetQmlItemNode.instanceSize().width() - fromAnchorLine;
|
||||||
|
else if (lineAnchorLineType == AnchorLine::Bottom)
|
||||||
|
margin = targetQmlItemNode.instanceSize().height() - fromAnchorLine;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qFuzzyIsNull(margin) || !qFuzzyIsNull(qmlAnchors.instanceMargin(lineAnchorLineType)))
|
||||||
|
qmlAnchors.setMargin(lineAnchorLineType, margin);
|
||||||
|
|
||||||
|
qmlAnchors.setAnchor(lineAnchorLineType, targetQmlItemNode, lineAnchorLineType);
|
||||||
|
} else if (!snappingOffsets.isEmpty()) {
|
||||||
|
targetQmlItemNode = findItemOnSnappingLine(sourceQmlItemNode, snappingOffsets, fromAnchorLine, lineAnchorLineType);
|
||||||
|
if (targetQmlItemNode.isValid() && !targetQmlItemNode.anchors().checkForCycle(lineAnchorLineType, sourceQmlItemNode)) {
|
||||||
|
double margin = fromAnchorLine - targetQmlItemNode.anchors().instanceAnchorLine(offsetAnchorLineType);
|
||||||
|
|
||||||
|
if (lineAnchorLineType == AnchorLine::Right
|
||||||
|
|| lineAnchorLineType == AnchorLine::Bottom)
|
||||||
|
margin *= -1.;
|
||||||
|
|
||||||
|
|
||||||
|
if (!qFuzzyIsNull(margin) || !qFuzzyIsNull(qmlAnchors.instanceMargin(lineAnchorLineType)))
|
||||||
|
qmlAnchors.setMargin(lineAnchorLineType, margin);
|
||||||
|
|
||||||
|
qmlAnchors.setAnchor(lineAnchorLineType, targetQmlItemNode, offsetAnchorLineType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snapper::adjustAnchoringOfItem(FormEditorItem *formEditorItem)
|
||||||
|
{
|
||||||
|
QmlItemNode qmlItemNode = formEditorItem->qmlItemNode();
|
||||||
|
QmlAnchors qmlAnchors = qmlItemNode.anchors();
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->leftSnappingLines(),
|
||||||
|
containerFormEditorItem()->rightSnappingOffsets(),
|
||||||
|
AnchorLine::Left,
|
||||||
|
AnchorLine::Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->topSnappingLines(),
|
||||||
|
containerFormEditorItem()->bottomSnappingOffsets(),
|
||||||
|
AnchorLine::Top,
|
||||||
|
AnchorLine::Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->bottomSnappingLines(),
|
||||||
|
containerFormEditorItem()->topSnappingOffsets(),
|
||||||
|
AnchorLine::Bottom,
|
||||||
|
AnchorLine::Top);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->rightSnappingLines(),
|
||||||
|
containerFormEditorItem()->leftSnappingOffsets(),
|
||||||
|
AnchorLine::Right,
|
||||||
|
AnchorLine::Left);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::Left) && !qmlAnchors.instanceHasAnchor(AnchorLine::Right)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->verticalCenterSnappingLines(),
|
||||||
|
SnapLineMap(),
|
||||||
|
AnchorLine::HorizontalCenter,
|
||||||
|
AnchorLine::HorizontalCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qmlAnchors.instanceHasAnchor(AnchorLine::Top) && !qmlAnchors.instanceHasAnchor(AnchorLine::Bottom)) {
|
||||||
|
adjustAnchorLine(qmlItemNode,
|
||||||
|
containerFormEditorItem()->qmlItemNode(),
|
||||||
|
containerFormEditorItem()->horizontalCenterSnappingLines(),
|
||||||
|
SnapLineMap(),
|
||||||
|
AnchorLine::VerticalCenter,
|
||||||
|
AnchorLine::VerticalCenter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//static void alignLine(QLineF &line)
|
//static void alignLine(QLineF &line)
|
||||||
//{
|
//{
|
||||||
// line.setP1(QPointF(std::floor(line.p1().x()) + 0.5,
|
// line.setP1(QPointF(std::floor(line.p1().x()) + 0.5,
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ namespace QmlDesigner {
|
|||||||
class Snapper
|
class Snapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum Snapping {
|
||||||
|
UseSnapping,
|
||||||
|
UseSnappingAndAnchoring,
|
||||||
|
NoSnapping
|
||||||
|
};
|
||||||
|
|
||||||
Snapper();
|
Snapper();
|
||||||
|
|
||||||
void setContainerFormEditorItem(FormEditorItem *formEditorItem);
|
void setContainerFormEditorItem(FormEditorItem *formEditorItem);
|
||||||
@@ -73,6 +79,9 @@ public:
|
|||||||
QList<QGraphicsItem*> generateSnappingLines(const QRectF &boundingRect,
|
QList<QGraphicsItem*> generateSnappingLines(const QRectF &boundingRect,
|
||||||
QGraphicsItem *layerItem,
|
QGraphicsItem *layerItem,
|
||||||
const QTransform &transform);
|
const QTransform &transform);
|
||||||
|
|
||||||
|
void adjustAnchoringOfItem(FormEditorItem *formEditorItem);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double snappedOffsetForLines(const SnapLineMap &snappingLineMap,
|
double snappedOffsetForLines(const SnapLineMap &snappingLineMap,
|
||||||
double value) const;
|
double value) const;
|
||||||
|
|||||||
@@ -92,6 +92,14 @@ public:
|
|||||||
void removeAnchors();
|
void removeAnchors();
|
||||||
bool instanceHasAnchor(AnchorLine::Type sourceAnchorLineType) const;
|
bool instanceHasAnchor(AnchorLine::Type sourceAnchorLineType) const;
|
||||||
bool instanceHasAnchors() const;
|
bool instanceHasAnchors() const;
|
||||||
|
double instanceLeftAnchorLine() const;
|
||||||
|
double instanceTopAnchorLine() const;
|
||||||
|
double instanceRightAnchorLine() const;
|
||||||
|
double instanceBottomAnchorLine() const;
|
||||||
|
double instanceHorizontalCenterAnchorLine() const;
|
||||||
|
double instanceVerticalCenterAnchorLine() const;
|
||||||
|
double instanceAnchorLine(AnchorLine::Type anchorLine) const;
|
||||||
|
|
||||||
void setMargin(AnchorLine::Type sourceAnchorLineType, double margin) const;
|
void setMargin(AnchorLine::Type sourceAnchorLineType, double margin) const;
|
||||||
bool instanceHasMargin(AnchorLine::Type sourceAnchorLineType) const;
|
bool instanceHasMargin(AnchorLine::Type sourceAnchorLineType) const;
|
||||||
double instanceMargin(AnchorLine::Type sourceAnchorLineType) const;
|
double instanceMargin(AnchorLine::Type sourceAnchorLineType) const;
|
||||||
@@ -101,8 +109,13 @@ public:
|
|||||||
void fill();
|
void fill();
|
||||||
void centerIn();
|
void centerIn();
|
||||||
|
|
||||||
protected:
|
bool checkForCycle(AnchorLine::Type anchorLineTyp, const QmlItemNode &sourceItem) const;
|
||||||
|
bool checkForHorizontalCycle(const QmlItemNode &sourceItem) const;
|
||||||
|
bool checkForVerticalCycle(const QmlItemNode &sourceItem) const;
|
||||||
|
|
||||||
QmlItemNode qmlItemNode() const;
|
QmlItemNode qmlItemNode() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
void beautify();
|
void beautify();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -396,6 +396,51 @@ bool QmlAnchors::instanceHasAnchors() const
|
|||||||
instanceHasAnchor(AnchorLine::Baseline);
|
instanceHasAnchor(AnchorLine::Baseline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceLeftAnchorLine() const
|
||||||
|
{
|
||||||
|
return qmlItemNode().nodeInstance().position().x();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceTopAnchorLine() const
|
||||||
|
{
|
||||||
|
return qmlItemNode().nodeInstance().position().y();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceRightAnchorLine() const
|
||||||
|
{
|
||||||
|
return qmlItemNode().nodeInstance().position().x() + qmlItemNode().nodeInstance().size().width();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceBottomAnchorLine() const
|
||||||
|
{
|
||||||
|
return qmlItemNode().nodeInstance().position().y() + qmlItemNode().nodeInstance().size().height();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceHorizontalCenterAnchorLine() const
|
||||||
|
{
|
||||||
|
return (instanceLeftAnchorLine() + instanceRightAnchorLine()) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceVerticalCenterAnchorLine() const
|
||||||
|
{
|
||||||
|
return (instanceBottomAnchorLine() + instanceTopAnchorLine()) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlAnchors::instanceAnchorLine(AnchorLine::Type anchorLine) const
|
||||||
|
{
|
||||||
|
switch (anchorLine) {
|
||||||
|
case AnchorLine::Left: return instanceLeftAnchorLine();
|
||||||
|
case AnchorLine::Top: return instanceTopAnchorLine();
|
||||||
|
case AnchorLine::Bottom: return instanceBottomAnchorLine();
|
||||||
|
case AnchorLine::Right: return instanceRightAnchorLine();
|
||||||
|
case AnchorLine::HorizontalCenter: return instanceHorizontalCenterAnchorLine();
|
||||||
|
case AnchorLine::VerticalCenter: return instanceVerticalCenterAnchorLine();
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlAnchors::setMargin(AnchorLine::Type sourceAnchorLineType, double margin) const
|
void QmlAnchors::setMargin(AnchorLine::Type sourceAnchorLineType, double margin) const
|
||||||
{
|
{
|
||||||
PropertyName propertyName = marginPropertyName(sourceAnchorLineType);
|
PropertyName propertyName = marginPropertyName(sourceAnchorLineType);
|
||||||
@@ -407,6 +452,71 @@ bool QmlAnchors::instanceHasMargin(AnchorLine::Type sourceAnchorLineType) const
|
|||||||
return !qIsNull(instanceMargin(sourceAnchorLineType));
|
return !qIsNull(instanceMargin(sourceAnchorLineType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool checkForHorizontalCycleRecusive(const QmlAnchors &anchors, QList<QmlItemNode> &visitedItems)
|
||||||
|
{
|
||||||
|
visitedItems.append(anchors.qmlItemNode());
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::Left)) {
|
||||||
|
AnchorLine leftAnchorLine = anchors.instanceAnchor(AnchorLine::Left);
|
||||||
|
if (visitedItems.contains(leftAnchorLine.qmlItemNode()) || checkForHorizontalCycleRecusive(leftAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::Right)) {
|
||||||
|
AnchorLine rightAnchorLine = anchors.instanceAnchor(AnchorLine::Right);
|
||||||
|
if (visitedItems.contains(rightAnchorLine.qmlItemNode()) || checkForHorizontalCycleRecusive(rightAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::HorizontalCenter)) {
|
||||||
|
AnchorLine horizontalCenterAnchorLine = anchors.instanceAnchor(AnchorLine::HorizontalCenter);
|
||||||
|
if (visitedItems.contains(horizontalCenterAnchorLine.qmlItemNode()) || checkForHorizontalCycleRecusive(horizontalCenterAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkForVerticalCycleRecusive(const QmlAnchors &anchors, QList<QmlItemNode> &visitedItems)
|
||||||
|
{
|
||||||
|
visitedItems.append(anchors.qmlItemNode());
|
||||||
|
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::Top)) {
|
||||||
|
AnchorLine topAnchorLine = anchors.instanceAnchor(AnchorLine::Top);
|
||||||
|
if (visitedItems.contains(topAnchorLine.qmlItemNode()) || checkForVerticalCycleRecusive(topAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::Bottom)) {
|
||||||
|
AnchorLine bottomAnchorLine = anchors.instanceAnchor(AnchorLine::Bottom);
|
||||||
|
if (visitedItems.contains(bottomAnchorLine.qmlItemNode()) || checkForVerticalCycleRecusive(bottomAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anchors.instanceHasAnchor(AnchorLine::VerticalCenter)) {
|
||||||
|
AnchorLine verticalCenterAnchorLine = anchors.instanceAnchor(AnchorLine::VerticalCenter);
|
||||||
|
if (visitedItems.contains(verticalCenterAnchorLine.qmlItemNode()) || checkForVerticalCycleRecusive(verticalCenterAnchorLine.qmlItemNode().anchors(), visitedItems))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlAnchors::checkForHorizontalCycle(const QmlItemNode &sourceItem) const
|
||||||
|
{
|
||||||
|
QList<QmlItemNode> visitedItems;
|
||||||
|
visitedItems.append(sourceItem);
|
||||||
|
|
||||||
|
return checkForHorizontalCycleRecusive(*this, visitedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlAnchors::checkForVerticalCycle(const QmlItemNode &sourceItem) const
|
||||||
|
{
|
||||||
|
QList<QmlItemNode> visitedItems;
|
||||||
|
visitedItems.append(sourceItem);
|
||||||
|
|
||||||
|
return checkForVerticalCycleRecusive(*this, visitedItems);
|
||||||
|
}
|
||||||
|
|
||||||
double QmlAnchors::instanceMargin(AnchorLine::Type sourceAnchorLineType) const
|
double QmlAnchors::instanceMargin(AnchorLine::Type sourceAnchorLineType) const
|
||||||
{
|
{
|
||||||
return qmlItemNode().nodeInstance().property(marginPropertyName(sourceAnchorLineType)).toDouble();
|
return qmlItemNode().nodeInstance().property(marginPropertyName(sourceAnchorLineType)).toDouble();
|
||||||
@@ -452,4 +562,12 @@ void QmlAnchors::centerIn()
|
|||||||
qmlItemNode().modelNode().bindingProperty("anchors.centerIn").setExpression("parent");
|
qmlItemNode().modelNode().bindingProperty("anchors.centerIn").setExpression("parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmlAnchors::checkForCycle(AnchorLine::Type anchorLineTyp, const QmlItemNode &sourceItem) const
|
||||||
|
{
|
||||||
|
if (anchorLineTyp & AnchorLine::HorizontalMask)
|
||||||
|
return checkForHorizontalCycle(sourceItem);
|
||||||
|
else
|
||||||
|
return checkForVerticalCycle(sourceItem);
|
||||||
|
}
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
Reference in New Issue
Block a user