/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtDeclarative module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "subcomponenteditortool_p.h" #include "subcomponentmasklayeritem_p.h" #include "livelayeritem_p.h" #include "../qdeclarativeviewobserver_p_p.h" #include #include #include #include #include #include QT_BEGIN_NAMESPACE const qreal MaxOpacity = 0.5f; SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view) : AbstractLiveEditTool(view), m_animIncrement(0.05f), m_animTimer(new QTimer(this)) { QDeclarativeViewObserverPrivate *observerPrivate = QDeclarativeViewObserverPrivate::get(view); m_mask = new SubcomponentMaskLayerItem(view, observerPrivate->manipulatorLayer); connect(m_animTimer, SIGNAL(timeout()), SLOT(animate())); m_animTimer->setInterval(20); } SubcomponentEditorTool::~SubcomponentEditorTool() { } void SubcomponentEditorTool::mousePressEvent(QMouseEvent * /*event*/) { } void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent * /*event*/) { } bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const { if (!m_currentContext.size()) return false; QPointF scenePos = view()->mapToScene(mousePos); QRectF itemRect = m_currentContext.top()->boundingRect() | m_currentContext.top()->childrenBoundingRect(); QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect(); return polyRect.contains(scenePos); } void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/) { } void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton && !containsCursor(event->pos()) && m_currentContext.size() > 1) { aboutToPopContext(); } } void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event) { if (!containsCursor(event->pos()) && m_currentContext.size() > 1) { QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); } } void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/) { } void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/) { } void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) { } void SubcomponentEditorTool::itemsAboutToRemoved(const QList &/*itemList*/) { } void SubcomponentEditorTool::animate() { if (m_animIncrement > 0) { if (m_mask->opacity() + m_animIncrement < MaxOpacity) { m_mask->setOpacity(m_mask->opacity() + m_animIncrement); } else { m_animTimer->stop(); m_mask->setOpacity(MaxOpacity); } } else { if (m_mask->opacity() + m_animIncrement > 0) { m_mask->setOpacity(m_mask->opacity() + m_animIncrement); } else { m_animTimer->stop(); m_mask->setOpacity(0); popContext(); emit contextPathChanged(m_path); } } } void SubcomponentEditorTool::clear() { m_currentContext.clear(); m_mask->setCurrentItem(0); m_animTimer->stop(); m_mask->hide(); m_path.clear(); emit contextPathChanged(m_path); emit cleared(); } void SubcomponentEditorTool::selectedItemsChanged(const QList &/*itemList*/) { } void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem) { if (!contextItem) return; QGraphicsObject *gfxObject = contextItem->toGraphicsObject(); if (!gfxObject) return; //QString parentClassName = gfxObject->metaObject()->className(); //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) bool containsSelectableItems = false; foreach (QGraphicsItem *item, gfxObject->childItems()) { if (item->type() == Constants::EditorItemType || item->type() == Constants::ResizeHandleItemType) { continue; } containsSelectableItems = true; break; } if (containsSelectableItems) { m_mask->setCurrentItem(gfxObject); m_mask->setOpacity(0); m_mask->show(); m_animIncrement = 0.05f; m_animTimer->start(); QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); observer()->setSelectedItems(QList()); pushContext(gfxObject); } } QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const { if (!item) return 0; if (isDirectChildOfContext(item)) return item; QGraphicsItem *parent = item->parentItem(); while (parent) { if (isDirectChildOfContext(parent)) return parent; parent = parent->parentItem(); } return 0; } bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const { return (firstChildOfContext(item) != 0); } bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const { return (item->parentItem() == m_currentContext.top()); } bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const { if (item->parentItem() && item->parentItem() != m_currentContext.top()) { QGraphicsObject *parent = item->parentItem()->toGraphicsObject(); QString parentClassName = QLatin1String(parent->metaObject()->className()); if (parentClassName.contains(QRegExp(QLatin1String("_QMLTYPE_\\d+")))) { return true; } else { return itemIsChildOfQmlSubComponent(parent); } } return false; } void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem) { connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*))); connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask())); connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask())); connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask())); connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask())); connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask())); m_currentContext.push(contextItem); QString title = titleForItem(contextItem); emit contextPushed(title); m_path << title; emit contextPathChanged(m_path); } void SubcomponentEditorTool::aboutToPopContext() { if (m_currentContext.size() > 2) { popContext(); emit contextPathChanged(m_path); } else { m_animIncrement = -0.05f; m_animTimer->start(); } } QGraphicsObject *SubcomponentEditorTool::popContext() { QGraphicsObject *popped = m_currentContext.pop(); m_path.removeLast(); emit contextPopped(); disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask())); disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask())); disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask())); disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask())); disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask())); if (m_currentContext.size() > 1) { QGraphicsObject *item = m_currentContext.top(); m_mask->setCurrentItem(item); m_mask->setOpacity(MaxOpacity); m_mask->setVisible(true); } else { m_mask->setVisible(false); } return popped; } void SubcomponentEditorTool::resizeMask() { QGraphicsObject *item = m_currentContext.top(); m_mask->setCurrentItem(item); } QGraphicsObject *SubcomponentEditorTool::currentRootItem() const { return m_currentContext.top(); } void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy) { disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*))); // pop out the whole context - it might not be safe anymore. while (m_currentContext.size() > 1) { m_currentContext.pop(); m_path.removeLast(); emit contextPopped(); } m_mask->setVisible(false); emit contextPathChanged(m_path); } QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex) { Q_ASSERT(contextIndex >= 0); // sometimes we have to delete the context while user was still clicking around, // so just bail out. if (contextIndex >= m_currentContext.size() -1) return 0; while (m_currentContext.size() - 1 > contextIndex) { popContext(); } emit contextPathChanged(m_path); return m_currentContext.top(); } int SubcomponentEditorTool::contextIndex() const { return m_currentContext.size() - 1; } QT_END_NAMESPACE