forked from qt-creator/qt-creator
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>
This commit is contained in:
committed by
Tim Jenssen
parent
04f19cf573
commit
9c2f2bed3a
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -64,6 +64,7 @@ public:
|
||||
void beginWithPoint(const QPointF &beginPoint);
|
||||
|
||||
void clear() override;
|
||||
void start() override;
|
||||
|
||||
void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) override;
|
||||
|
||||
|
@@ -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)) {
|
||||
|
@@ -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));
|
||||
|
@@ -89,6 +89,7 @@ private:
|
||||
ContentNotEditableIndicator m_contentNotEditableIndicator;
|
||||
QTime m_mousePressTimer;
|
||||
QCursor m_cursor;
|
||||
bool m_itemAlreadySelected = false;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
Reference in New Issue
Block a user