diff options
author | Thomas Hartmann <thomas.hartmann@qt.io> | 2017-06-30 18:20:56 +0200 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@qt.io> | 2017-07-19 12:16:41 +0000 |
commit | 9c2f2bed3a5187b259f51a3138baf220b9f3a148 (patch) | |
tree | 09e2bd21e156e22a148e008a159998598e77c393 | |
parent | 04f19cf5732c30fabd62375cbf692e6286d62127 (diff) |
QmlDesigner: Refine selection
This is a major overhaul of the slection logic.
We do not change to the move tool automatically once
the curser enters the selected item. This allows selection
of items that are at the same position as the current selected item.
The selected item can still be moved if there is no pissible candidate for
selection. Also the border and gizmo always allows an item to be moved, if
the item is fully covered by another item.
Change-Id: Ic97a2bf23f33fcc5e209248aeb2f97df67bd23e1
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
9 files changed, 82 insertions, 8 deletions
diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp index f743814bc7..291f17fad5 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp @@ -131,7 +131,31 @@ bool AbstractFormEditorTool::topSelectedItemIsMovable(const QList<QGraphicsItem* } return false; +} + +bool AbstractFormEditorTool::selectedItemCursorInMovableArea(const QPointF &pos) +{ + if (!view()->hasSingleSelectedModelNode()) + return false; + + const ModelNode selectedNode = view()->singleSelectedModelNode(); + + FormEditorItem *item = scene()->itemForQmlItemNode(selectedNode); + + if (!item) + return false; + if (!topSelectedItemIsMovable({item})) + return false; + + const QPolygonF boundingRectInSceneSpace(item->mapToScene(item->qmlItemNode().instanceBoundingRect())); + QRectF boundingRect = boundingRectInSceneSpace.boundingRect(); + QRectF innerRect = boundingRect; + + innerRect.adjust(10, 10, -10, -10); + boundingRect.adjust(-10, -20, 10, 10); + + return !innerRect.contains(pos) && boundingRect.contains(pos); } bool AbstractFormEditorTool::topItemIsResizeHandle(const QList<QGraphicsItem*> &/*itemList*/) @@ -328,4 +352,9 @@ void AbstractFormEditorTool::clear() { m_itemList.clear(); } + +void AbstractFormEditorTool::start() +{ + +} } diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h index e62975e21c..02cbc5a289 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h @@ -67,6 +67,7 @@ public: // const QVariant &value ) = 0; // virtual void update() = 0; virtual void clear(); + virtual void start(); virtual void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) = 0; @@ -84,6 +85,7 @@ public: static FormEditorItem* topMovableFormEditorItem(const QList<QGraphicsItem*> &itemList, bool selectOnlyContentItems); bool topItemIsMovable(const QList<QGraphicsItem*> &itemList); bool topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList); + bool selectedItemCursorInMovableArea(const QPointF &pos); bool topItemIsResizeHandle(const QList<QGraphicsItem*> &itemList); QList<FormEditorItem*> filterSelectedModelNodes(const QList<FormEditorItem*> &itemList) const; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 3833c3682c..1ec725d6cd 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -411,6 +411,7 @@ void FormEditorView::changeCurrentToolTo(AbstractFormEditorTool *newTool) m_currentTool->clear(); m_currentTool->setItems(scene()->itemsForQmlItemNodes(toQmlItemNodeList( selectedModelNodes()))); + m_currentTool->start(); } void FormEditorView::registerTool(AbstractCustomTool *tool) diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp index 52c782eaa4..ecca77a73d 100644 --- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp @@ -27,6 +27,8 @@ #include "layeritem.h" #include "formeditoritem.h" #include "formeditorscene.h" +#include "formeditorwidget.h" +#include "formeditorgraphicsview.h" #include <qmlanchors.h> #include <nodehints.h> @@ -129,6 +131,7 @@ void MoveManipulator::setDirectUpdateInNodeInstances(bool directUpdate) void MoveManipulator::begin(const QPointF &beginPoint) { + m_view->formEditorWidget()->graphicsView()->viewport()->setCursor(Qt::SizeAllCursor); m_isActive = true; m_snapper.updateSnappingLines(m_itemList); @@ -377,6 +380,7 @@ void MoveManipulator::reparentTo(FormEditorItem *newParent) void MoveManipulator::end() { + m_view->formEditorWidget()->graphicsView()->viewport()->unsetCursor(); setDirectUpdateInNodeInstances(false); m_isActive = false; deleteSnapLines(); diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.cpp b/src/plugins/qmldesigner/components/formeditor/movetool.cpp index ebd32c1bba..fba74d9b3c 100644 --- a/src/plugins/qmldesigner/components/formeditor/movetool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movetool.cpp @@ -28,6 +28,7 @@ #include "formeditorscene.h" #include "formeditorview.h" #include "formeditorwidget.h" +#include "formeditorgraphicsview.h" #include "resizehandleitem.h" @@ -66,6 +67,12 @@ void MoveTool::clear() m_contentNotEditableIndicator.clear(); AbstractFormEditorTool::clear(); + view()->formEditorWidget()->graphicsView()->viewport()->unsetCursor(); +} + +void MoveTool::start() +{ + view()->formEditorWidget()->graphicsView()->viewport()->setCursor(Qt::SizeAllCursor); } void MoveTool::mousePressEvent(const QList<QGraphicsItem*> &itemList, @@ -115,7 +122,7 @@ void MoveTool::mouseMoveEvent(const QList<QGraphicsItem*> &itemList, } void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList, - QGraphicsSceneMouseEvent * /*event*/) + QGraphicsSceneMouseEvent * event) { if (itemList.isEmpty()) { view()->changeToSelectionTool(); @@ -133,6 +140,18 @@ void MoveTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList, return; } + if (view()->hasSingleSelectedModelNode() && !selectedItemCursorInMovableArea(event->scenePos())) { + view()->changeToSelectionTool(); + return; + } + + if (event->modifiers().testFlag(Qt::ShiftModifier) + || event->modifiers().testFlag(Qt::ControlModifier) ) { + view()->changeToSelectionTool(); + return; + } + + m_contentNotEditableIndicator.setItems(toFormEditorItemList(itemList)); } @@ -224,6 +243,8 @@ void MoveTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList, m_movingItems.clear(); } + view()->changeToSelectionTool(); + AbstractFormEditorTool::mouseReleaseEvent(itemList, event); } diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.h b/src/plugins/qmldesigner/components/formeditor/movetool.h index 8aab108eb5..0092d6757d 100644 --- a/src/plugins/qmldesigner/components/formeditor/movetool.h +++ b/src/plugins/qmldesigner/components/formeditor/movetool.h @@ -64,6 +64,7 @@ public: void beginWithPoint(const QPointF &beginPoint); void clear() override; + void start() override; void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) override; diff --git a/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp b/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp index fc9d338aff..c1b26877ad 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp @@ -109,7 +109,6 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList) pen.setJoinStyle(Qt::MiterJoin); pen.setColor(selectionColor); newSelectionIndicatorGraphicsItem->setPen(pen); - newSelectionIndicatorGraphicsItem->setCursor(m_cursor); } if (checkSingleSelection(itemList)) { diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp index a187682bf4..3aa1c2c1fd 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp @@ -26,6 +26,8 @@ #include "selectiontool.h" #include "formeditorscene.h" #include "formeditorview.h" +#include "formeditorwidget.h" +#include "formeditorgraphicsview.h" #include "resizehandleitem.h" @@ -64,14 +66,16 @@ void SelectionTool::mousePressEvent(const QList<QGraphicsItem*> &itemList, m_mousePressTimer.start(); FormEditorItem* formEditorItem = nearestFormEditorItem(event->scenePos(), itemList); if (formEditorItem - && formEditorItem->qmlItemNode().isValid() - && !formEditorItem->qmlItemNode().hasChildren()) { + && formEditorItem->qmlItemNode().isValid()) { m_singleSelectionManipulator.begin(event->scenePos()); + m_itemAlreadySelected = toQmlItemNodeList(view()->selectedModelNodes()).contains(formEditorItem->qmlItemNode()) + || !view()->hasSingleSelectedModelNode(); + if (event->modifiers().testFlag(Qt::ControlModifier)) - m_singleSelectionManipulator.select(SingleSelectionManipulator::RemoveFromSelection); + m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection); else if (event->modifiers().testFlag(Qt::ShiftModifier)) - m_singleSelectionManipulator.select(SingleSelectionManipulator::AddToSelection); + m_singleSelectionManipulator.select(SingleSelectionManipulator::InvertSelection); else m_singleSelectionManipulator.select(SingleSelectionManipulator::ReplaceSelection); } else { @@ -104,7 +108,8 @@ void SelectionTool::mouseMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, if ((mouseMovementVector.toPoint().manhattanLength() > s_startDragDistance) && (m_mousePressTimer.elapsed() > s_startDragTime)) { m_singleSelectionManipulator.end(event->scenePos()); - view()->changeToMoveTool(m_singleSelectionManipulator.beginPoint()); + if (m_itemAlreadySelected) + view()->changeToMoveTool(m_singleSelectionManipulator.beginPoint()); return; } } else if (m_rubberbandSelectionManipulator.isActive()) { @@ -134,7 +139,10 @@ void SelectionTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList, return; } - if (topSelectedItemIsMovable(itemList)) { + if ((topSelectedItemIsMovable(itemList) && !view()->hasSingleSelectedModelNode()) + || selectedItemCursorInMovableArea(event->scenePos()) + && !event->modifiers().testFlag(Qt::ControlModifier) + && !event->modifiers().testFlag(Qt::ShiftModifier)) { view()->changeToMoveTool(); return; } @@ -142,6 +150,14 @@ void SelectionTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList, FormEditorItem *topSelectableItem = nearestFormEditorItem(event->scenePos(), itemList); + + if (topSelectableItem && toQmlItemNodeList(view()->selectedModelNodes()).contains(topSelectableItem->qmlItemNode()) + && topSelectedItemIsMovable({topSelectableItem})) { + view()->formEditorWidget()->graphicsView()->viewport()->setCursor(Qt::SizeAllCursor); + } else { + view()->formEditorWidget()->graphicsView()->viewport()->unsetCursor(); + } + scene()->highlightBoundingRect(topSelectableItem); m_contentNotEditableIndicator.setItems(toFormEditorItemList(itemList)); diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.h b/src/plugins/qmldesigner/components/formeditor/selectiontool.h index 0a5945c735..154a57f223 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectiontool.h +++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.h @@ -89,6 +89,7 @@ private: ContentNotEditableIndicator m_contentNotEditableIndicator; QTime m_mousePressTimer; QCursor m_cursor; + bool m_itemAlreadySelected = false; }; } // namespace QmlDesigner |