From 000e468d00ef7080935b86ff16bba8609a820cc8 Mon Sep 17 00:00:00 2001 From: Lasse Holmstedt <lasse.holmstedt@nokia.com> Date: Wed, 4 Aug 2010 18:53:01 +0200 Subject: [PATCH] QML Observer: Fixed bug w/selection boxes being visible after delesect --- .../editor/boundingrecthighlighter.cpp | 120 +++++++++--------- .../editor/boundingrecthighlighter.h | 34 ++++- .../editor/selectionindicator.cpp | 43 ++++--- .../qmljsdebugger/editor/selectiontool.cpp | 35 ++--- .../qmljsdebugger/qdeclarativedesignview.cpp | 17 ++- .../qmljsdebugger/qdeclarativedesignview_p.h | 4 +- 6 files changed, 142 insertions(+), 111 deletions(-) diff --git a/src/libs/qmljsdebugger/editor/boundingrecthighlighter.cpp b/src/libs/qmljsdebugger/editor/boundingrecthighlighter.cpp index 90fb9446ebb..9ac50433fd2 100644 --- a/src/libs/qmljsdebugger/editor/boundingrecthighlighter.cpp +++ b/src/libs/qmljsdebugger/editor/boundingrecthighlighter.cpp @@ -4,6 +4,7 @@ #include <QGraphicsPolygonItem> #include <QTimer> +#include <QObject> #include <QDebug> @@ -13,29 +14,9 @@ const qreal AnimDelta = 0.025f; const int AnimInterval = 30; const int AnimFrames = 10; -class BoundingBoxPolygonItem : public QGraphicsPolygonItem -{ -public: - explicit BoundingBoxPolygonItem(QGraphicsItem *item); - int type() const; -}; - -class BoundingBox -{ -public: - explicit BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem); - ~BoundingBox(); - QWeakPointer<QGraphicsObject> highlightedObject; - QGraphicsPolygonItem *highlightPolygon; - QGraphicsPolygonItem *highlightPolygonEdge; - -private: - Q_DISABLE_COPY(BoundingBox); - -}; - -BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem) - : highlightedObject(itemToHighlight), +BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, QObject *parent) + : QObject(parent), + highlightedObject(itemToHighlight), highlightPolygon(0), highlightPolygonEdge(0) { @@ -51,10 +32,6 @@ BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parent BoundingBox::~BoundingBox() { - delete highlightPolygon; - delete highlightPolygonEdge; - highlightPolygon = 0; - highlightPolygonEdge = 0; highlightedObject.clear(); } @@ -80,6 +57,11 @@ BoundingRectHighlighter::BoundingRectHighlighter(QDeclarativeDesignView *view) : connect(m_animTimer, SIGNAL(timeout()), SLOT(animTimeout())); } +BoundingRectHighlighter::~BoundingRectHighlighter() +{ + +} + void BoundingRectHighlighter::animTimeout() { ++m_animFrame; @@ -100,17 +82,8 @@ void BoundingRectHighlighter::clear() m_animTimer->stop(); foreach(BoundingBox *box, m_boxes) { - if (!box->highlightedObject.isNull()) { - disconnect(box->highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh())); - disconnect(box->highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh())); - disconnect(box->highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh())); - disconnect(box->highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh())); - disconnect(box->highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh())); - } + freeBoundingBox(box); } - - qDeleteAll(m_boxes); - m_boxes.clear(); } } @@ -131,8 +104,7 @@ void BoundingRectHighlighter::highlight(QList<QGraphicsObject*> items) bool animate = false; - QList<BoundingBox*> newBoxes; - + QList<BoundingBox *> newBoxes; foreach(QGraphicsObject *itemToHighlight, items) { BoundingBox *box = boxFor(itemToHighlight); if (!box) { @@ -172,26 +144,71 @@ void BoundingRectHighlighter::highlight(QGraphicsObject* itemToHighlight) BoundingBox *BoundingRectHighlighter::createBoundingBox(QGraphicsObject *itemToHighlight) { - BoundingBox *box = new BoundingBox(itemToHighlight, this); + if (!m_freeBoxes.isEmpty()) { + BoundingBox *box = m_freeBoxes.last(); + if (box->highlightedObject.isNull()) { + box->highlightedObject = itemToHighlight; + box->highlightPolygon->show(); + box->highlightPolygonEdge->show(); + m_freeBoxes.removeLast(); + return box; + } + } + + BoundingBox *box = new BoundingBox(itemToHighlight, this, this); connect(itemToHighlight, SIGNAL(xChanged()), this, SLOT(refresh())); connect(itemToHighlight, SIGNAL(yChanged()), this, SLOT(refresh())); connect(itemToHighlight, SIGNAL(widthChanged()), this, SLOT(refresh())); connect(itemToHighlight, SIGNAL(heightChanged()), this, SLOT(refresh())); connect(itemToHighlight, SIGNAL(rotationChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*))); return box; } -void BoundingRectHighlighter::highlightAll(bool animate) +void BoundingRectHighlighter::removeBoundingBox(BoundingBox *box) +{ + delete box; + box = 0; +} + +void BoundingRectHighlighter::freeBoundingBox(BoundingBox *box) +{ + if (!box->highlightedObject.isNull()) { + disconnect(box->highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh())); + } + + box->highlightedObject.clear(); + box->highlightPolygon->hide(); + box->highlightPolygonEdge->hide(); + m_boxes.removeOne(box); + m_freeBoxes << box; +} + +void BoundingRectHighlighter::itemDestroyed(QObject *obj) { foreach(BoundingBox *box, m_boxes) { - QGraphicsObject *item = box->highlightedObject.data(); - if (box->highlightedObject.isNull()) { - m_boxes.removeOne(box); - continue; + if (box->highlightedObject.data() == obj) { + freeBoundingBox(box); + break; } + } +} +void BoundingRectHighlighter::highlightAll(bool animate) +{ + foreach(BoundingBox *box, m_boxes) { + if (box && box->highlightedObject.isNull()) { + // clear all highlights + clear(); + return; + } + QGraphicsObject *item = box->highlightedObject.data(); QRectF itemAndChildRect = item->boundingRect() | item->childrenBoundingRect(); QPolygonF boundingRectInSceneSpace(item->mapToScene(itemAndChildRect)); @@ -213,19 +230,6 @@ void BoundingRectHighlighter::highlightAll(bool animate) } } -void BoundingRectHighlighter::removeHighlight(QGraphicsObject *item) -{ - if (!item) - return; - - BoundingBox *box = boxFor(item); - if (box) { - m_boxes.removeOne(box); - delete box; - box = 0; - } -} - void BoundingRectHighlighter::refresh() { if (!m_boxes.isEmpty()) diff --git a/src/libs/qmljsdebugger/editor/boundingrecthighlighter.h b/src/libs/qmljsdebugger/editor/boundingrecthighlighter.h index 948de90b13b..139b1ac7877 100644 --- a/src/libs/qmljsdebugger/editor/boundingrecthighlighter.h +++ b/src/libs/qmljsdebugger/editor/boundingrecthighlighter.h @@ -22,35 +22,57 @@ class BoundingRectHighlighter : public LayerItem Q_OBJECT public: explicit BoundingRectHighlighter(QDeclarativeDesignView *view); + ~BoundingRectHighlighter(); void clear(); void highlight(QList<QGraphicsObject*> items); void highlight(QGraphicsObject* item); - void removeHighlight(QGraphicsObject *item); private slots: void refresh(); void animTimeout(); + void itemDestroyed(QObject *); private: BoundingBox *boxFor(QGraphicsObject *item) const; void highlightAll(bool animate); BoundingBox *createBoundingBox(QGraphicsObject *itemToHighlight); + void removeBoundingBox(BoundingBox *box); + void freeBoundingBox(BoundingBox *box); private: Q_DISABLE_COPY(BoundingRectHighlighter); QDeclarativeDesignView *m_view; - QList<BoundingBox*> m_boxes; -// QList<QWeakPointer<QGraphicsObject> > m_highlightedObjects; -// QGraphicsPolygonItem *m_highlightPolygon; -// QGraphicsPolygonItem *m_highlightPolygonEdge; - + QList<BoundingBox* > m_boxes; + QList<BoundingBox* > m_freeBoxes; QTimer *m_animTimer; qreal m_animScale; int m_animFrame; }; +class BoundingBox : public QObject +{ + Q_OBJECT +public: + explicit BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, QObject *parent = 0); + ~BoundingBox(); + QWeakPointer<QGraphicsObject> highlightedObject; + QGraphicsPolygonItem *highlightPolygon; + QGraphicsPolygonItem *highlightPolygonEdge; + +private: + Q_DISABLE_COPY(BoundingBox); + +}; + +class BoundingBoxPolygonItem : public QGraphicsPolygonItem +{ +public: + explicit BoundingBoxPolygonItem(QGraphicsItem *item); + int type() const; +}; + } // namespace QmlViewer #endif // BOUNDINGRECTHIGHLIGHTER_H diff --git a/src/libs/qmljsdebugger/editor/selectionindicator.cpp b/src/libs/qmljsdebugger/editor/selectionindicator.cpp index e1e1a718531..8b303276b81 100644 --- a/src/libs/qmljsdebugger/editor/selectionindicator.cpp +++ b/src/libs/qmljsdebugger/editor/selectionindicator.cpp @@ -34,6 +34,7 @@ #include <QPen> #include <cmath> #include <QGraphicsScene> +#include <QDebug> namespace QmlViewer { @@ -61,11 +62,17 @@ void SelectionIndicator::hide() void SelectionIndicator::clear() { - if (m_layerItem) { - foreach (QGraphicsItem *item, m_indicatorShapeHash.values()) - m_layerItem->scene()->removeItem(item); + if (!m_layerItem.isNull()) { + QHashIterator<QGraphicsItem*, QGraphicsPolygonItem *> iter(m_indicatorShapeHash); + while(iter.hasNext()) { + iter.next(); + m_layerItem->scene()->removeItem(iter.value()); + delete iter.value(); + } } + m_indicatorShapeHash.clear(); + } QPolygonF SelectionIndicator::addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon) @@ -94,20 +101,22 @@ void SelectionIndicator::setItems(const QList<QWeakPointer<QGraphicsObject> > &i QGraphicsItem *item = obj.data(); QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data()); - m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem); - - QPolygonF boundingShapeInSceneSpace; - addBoundingRectToPolygon(item, boundingShapeInSceneSpace); - - QRectF boundingRect = m_view->adjustToScreenBoundaries(boundingShapeInSceneSpace.boundingRect()); - QPolygonF boundingRectInLayerItemSpace = m_layerItem->mapFromScene(boundingRect); - - QPen pen; - pen.setColor(QColor(108, 141, 221)); - newSelectionIndicatorGraphicsItem->setData(Constants::EditorItemDataKey, QVariant(true)); - newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false); - newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace); - newSelectionIndicatorGraphicsItem->setPen(pen); + if (!m_indicatorShapeHash.contains(item)) { + m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem); + + QPolygonF boundingShapeInSceneSpace; + addBoundingRectToPolygon(item, boundingShapeInSceneSpace); + + QRectF boundingRect = m_view->adjustToScreenBoundaries(boundingShapeInSceneSpace.boundingRect()); + QPolygonF boundingRectInLayerItemSpace = m_layerItem->mapFromScene(boundingRect); + + QPen pen; + pen.setColor(QColor(108, 141, 221)); + newSelectionIndicatorGraphicsItem->setData(Constants::EditorItemDataKey, QVariant(true)); + newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false); + newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace); + newSelectionIndicatorGraphicsItem->setPen(pen); + } } } diff --git a/src/libs/qmljsdebugger/editor/selectiontool.cpp b/src/libs/qmljsdebugger/editor/selectiontool.cpp index d40457e9fc8..004b926b5e6 100644 --- a/src/libs/qmljsdebugger/editor/selectiontool.cpp +++ b/src/libs/qmljsdebugger/editor/selectiontool.cpp @@ -223,7 +223,8 @@ void SelectionTool::contextMenuElementHovered(QAction *action) { int itemListIndex = action->data().toInt(); if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) { - QDeclarativeDesignViewPrivate::get(view())->highlight(m_contextMenuItemList.at(itemListIndex)); + QGraphicsObject *item = m_contextMenuItemList.at(itemListIndex)->toGraphicsObject(); + QDeclarativeDesignViewPrivate::get(view())->highlight(item); } } @@ -258,9 +259,10 @@ void SelectionTool::mouseMoveEvent(QMouseEvent *event) void SelectionTool::hoverMoveEvent(QMouseEvent * event) { - QList<QGraphicsItem*> itemList = view()->items(event->pos()); - if (!itemList.isEmpty() && !m_rubberbandSelectionMode) { - +// ### commented out until move tool is re-enabled +// QList<QGraphicsItem*> itemList = view()->items(event->pos()); +// if (!itemList.isEmpty() && !m_rubberbandSelectionMode) { +// // foreach(QGraphicsItem *item, itemList) { // if (item->type() == Constants::ResizeHandleItemType) { // ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(item); @@ -271,27 +273,17 @@ void SelectionTool::hoverMoveEvent(QMouseEvent * event) // } // if (topSelectedItemIsMovable(itemList)) // view()->changeTool(Constants::MoveToolMode); - } - - QList<QGraphicsItem*> selectableItemList = view()->items(event->pos()); +// } + QList<QGraphicsItem*> selectableItemList = QDeclarativeDesignViewPrivate::get(view())->selectableItems(event->pos()); if (!selectableItemList.isEmpty()) { - QGraphicsItem *topSelectableItem = 0; - foreach(QGraphicsItem* item, selectableItemList) - { - if (!QDeclarativeDesignViewPrivate::get(view())->isEditorItem(item) - /*&& !item->qmlItemNode().isRootNode() - && (QGraphicsItem->qmlItemNode().hasShowContent() || !m_selectOnlyContentItems)*/) - { - topSelectableItem = item; - break; - } - } + QGraphicsObject *item = selectableItemList.first()->toGraphicsObject(); + if (item) + QDeclarativeDesignViewPrivate::get(view())->highlight(item); - QDeclarativeDesignViewPrivate::get(view())->highlight(topSelectableItem); - } else { - QDeclarativeDesignViewPrivate::get(view())->clearHighlight(); + return; } + QDeclarativeDesignViewPrivate::get(view())->clearHighlight(); } void SelectionTool::mouseReleaseEvent(QMouseEvent *event) @@ -416,6 +408,7 @@ void SelectionTool::selectedItemsChanged(const QList<QGraphicsItem*> &itemList) disconnect(obj.data(), SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects())); } } + QList<QGraphicsObject*> objects = toGraphicsObjectList(itemList); m_selectedItemList.clear(); diff --git a/src/libs/qmljsdebugger/qdeclarativedesignview.cpp b/src/libs/qmljsdebugger/qdeclarativedesignview.cpp index 80c6140e8cb..db6901b58d7 100644 --- a/src/libs/qmljsdebugger/qdeclarativedesignview.cpp +++ b/src/libs/qmljsdebugger/qdeclarativedesignview.cpp @@ -406,18 +406,17 @@ QList<QGraphicsItem *> QDeclarativeDesignView::selectedItems() return data->selectedItems(); } - void QDeclarativeDesignViewPrivate::clearHighlight() { boundingRectHighlighter->clear(); } -void QDeclarativeDesignViewPrivate::highlight(QGraphicsItem * item, ContextFlags flags) +void QDeclarativeDesignViewPrivate::highlight(QGraphicsObject * item, ContextFlags flags) { - highlight(QList<QGraphicsItem*>() << item, flags); + highlight(QList<QGraphicsObject*>() << item, flags); } -void QDeclarativeDesignViewPrivate::highlight(QList<QGraphicsItem *> items, ContextFlags flags) +void QDeclarativeDesignViewPrivate::highlight(QList<QGraphicsObject *> items, ContextFlags flags) { if (items.isEmpty()) return; @@ -627,15 +626,19 @@ void QDeclarativeDesignViewPrivate::_q_onStatusChanged(QDeclarativeView::Status void QDeclarativeDesignViewPrivate::_q_onCurrentObjectsChanged(QList<QObject*> objects) { QList<QGraphicsItem*> items; + QList<QGraphicsObject*> gfxObjects; foreach(QObject *obj, objects) { QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(obj); - if (declarativeItem) + if (declarativeItem) { items << declarativeItem; + QGraphicsObject *gfxObj = declarativeItem->toGraphicsObject(); + if (gfxObj) + gfxObjects << gfxObj; + } } - setSelectedItemsForTools(items); clearHighlight(); - highlight(items, QDeclarativeDesignViewPrivate::IgnoreContext); + highlight(gfxObjects, QDeclarativeDesignViewPrivate::IgnoreContext); } QString QDeclarativeDesignView::idStringForObject(QObject *obj) diff --git a/src/libs/qmljsdebugger/qdeclarativedesignview_p.h b/src/libs/qmljsdebugger/qdeclarativedesignview_p.h index 9ff33421f71..c06c018d0a6 100644 --- a/src/libs/qmljsdebugger/qdeclarativedesignview_p.h +++ b/src/libs/qmljsdebugger/qdeclarativedesignview_p.h @@ -102,8 +102,8 @@ public: Constants::ToolFlags flags = Constants::NoToolFlags); void clearHighlight(); - void highlight(QList<QGraphicsItem *> item, ContextFlags flags = ContextSensitive); - void highlight(QGraphicsItem *item, ContextFlags flags = ContextSensitive); + void highlight(QList<QGraphicsObject *> item, ContextFlags flags = ContextSensitive); + void highlight(QGraphicsObject *item, ContextFlags flags = ContextSensitive); bool mouseInsideContextItem() const; bool isEditorItem(QGraphicsItem *item) const; -- GitLab