diff -r 000000000000 -r 1450b09d0cfd ginebra2/ChromeSnippet.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ginebra2/ChromeSnippet.cpp Tue May 04 12:39:35 2010 +0300 @@ -0,0 +1,396 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "ChromeSnippet.h" +#include "VisibilityAnimator.h" +#include "GraphicsItemAnimation.h" +#include "ScriptObjects.h" +#include "ChromeRenderer.h" +#include "WebChromeItem.h" +#include + +#include + +namespace GVA { + + ChromeSnippet::ChromeSnippet(const QString & elementId, ChromeWidget * chrome, QGraphicsWidget * widget, const QWebElement & element) + : m_elementId(elementId), + m_element(element), + m_parentId(QString()), + m_chrome(chrome), + m_widget(widget), + m_initiallyVisible(false), // NB: not needed? + m_visible(m_initiallyVisible), + m_hidesContent(false), + m_anchor(anchorNone), + m_anchorOffset(0), + m_vAnimator(0), + m_effect(0), + m_hiding(0), + m_dontshowFlag (false) + { + setObjectName(m_elementId); //This will be the name under which the snippet is visible in snippets js object + if(m_widget) + m_widget->hide(); + //When chrome is resized child snippets may need to be repositioned + QObject::connect(m_chrome->renderer(), SIGNAL(chromeResized()), this, SLOT(positionChildren())); + QObject::connect(m_chrome, SIGNAL(chromeComplete()), this, SLOT(onChromeComplete())); + + // widget->setFlags(QGraphicsItem::ItemIsFocusable); + } + + ChromeSnippet::~ChromeSnippet() + { + //NB: Fix QObject parent relationships so we don't have to explicitly delete all these + + delete m_effect; + // Snippet has taken ownership of m_widget, so delete it. + // delete m_widget; + delete m_vAnimator; + } + + //This method slot is not actually hooked up in the base ChromeSnippet class. + //Instead, specializations of this class can hook it up to their underlying + //widget implementations as appropriate. Currently this hooked up in WebChromeSnippet + //to the webkit context menu. + + void ChromeSnippet::onContextMenuEvent(QGraphicsSceneContextMenuEvent * ev) + { + qDebug() << "ChromeSnippet::contextMenuEvent: " << ev->pos(); + emit contextMenuEvent(ev->pos().x(), ev->pos().y()); + } + + + //NB: Would be architecturally cleaner to do this translation in ChromeDOM + //so snippets don't have to know anything about dom attribute string values + + void ChromeSnippet::setAnchor(const QString& anchor, bool update) + { + + if(anchor == "AnchorTop") + setAnchor(anchorTop); + else if (anchor == "AnchorBottom") + setAnchor(anchorBottom); + else if (anchor == "AnchorCenter") + setAnchor(anchorCenter); + else if (anchor == "AnchorLeft") + setAnchor(anchorLeft); + else if (anchor == "AnchorRight") + setAnchor(anchorRight); + else if (anchor == "AnchorTopLeft") + setAnchor(anchorTopLeft); + else if (anchor == "AnchorTopRight") + setAnchor(anchorTopRight); + else if (anchor == "AnchorBottomLeft") + setAnchor(anchorBottomLeft); + else if (anchor == "AnchorBottomRight") + setAnchor(anchorBottomRight); + else + setAnchor(anchorNone); + if(update) + m_chrome->anchorSnippet(this); + } + + void ChromeSnippet::setAnchorOffset(int offset, bool update) + { + int delta = offset - m_anchorOffset; + m_anchorOffset = offset; + + if(update){ + if(m_widget->isVisible()) + m_chrome->adjustAnchorOffset(this, delta); + m_chrome->anchorSnippet(this); + } + } + + QString ChromeSnippet::getAnchorString() { + switch(anchor()) { + case anchorTop: + return "AnchorTop"; + case anchorBottom: + return "AnchorBottom"; + case anchorCenter: + return "AnchorCenter"; + case anchorLeft: + return "AnchorLeft"; + case anchorRight: + return "AnchorRight"; + case anchorTopLeft: + return "AnchorTopLeft"; + case anchorTopRight: + return "AnchorTopRight"; + case anchorBottomLeft: + return "AnchorBottomLeft"; + case anchorBottomRight: + return "AnchorBottomRight"; + default: + return QString::null; + } + } + + + void ChromeSnippet::setVisible(bool visibility, bool animate) + { + if(m_visible == visibility) + return; + m_visible = visibility; + if(m_visible) { + + //Visibility animators might leave the snippet + //in some visual state where it cannot be properly shown (e.g. transparent) + //on a previous hide. If no animation is wanted, we need to ask the + //animator to put the snippet back into a showable state before we show it. + + if(m_vAnimator && !animate) + m_vAnimator->setVisible(m_visible, animate); + m_widget->show(); + if(m_vAnimator && animate) + m_vAnimator->setVisible(m_visible, animate); + m_chrome->snippetShown(this); //NB: handle this via shown signal + m_hiding = false; + emit shown(); + } + else{ + m_chrome->snippetHiding(this); //NB: handle this via hiding signal + m_hiding = true; + emit hidden(); + if(m_vAnimator) + m_vAnimator->setVisible(m_visible, animate); + else + m_widget->hide(); + } + } + + void ChromeSnippet::visibilityFinished(bool visible) + { + if(!visible) + m_widget->hide(); + } + + void ChromeSnippet::toggleVisibility(bool animate) + { + setVisible(!m_visible, animate); + } + + void ChromeSnippet::setOpacity(qreal opacity) + { + m_widget->setOpacity(opacity); + } + + + qreal ChromeSnippet::opacity() + { + return m_widget->opacity(); + } + + //NB: Move effects to a separate class factory + + void ChromeSnippet::setEffect(const QString & effect) + { + if(effect=="Shadow"){ + m_effect = new QGraphicsDropShadowEffect(); + static_cast(m_effect)->setOffset(3.0,3.0); + static_cast(m_effect)->setBlurRadius(3.0); + } + else if (effect=="Blur"){ + m_effect = new QGraphicsBlurEffect(); + static_cast(m_effect)->setBlurRadius(3.0); + } + else if (effect=="Glow"){ + m_effect = new QGraphicsDropShadowEffect(); + static_cast(m_effect)->setOffset(1.0,1.0); + static_cast(m_effect)->setBlurRadius(5.0); + static_cast(m_effect)->setColor(Qt::green); + } + else + return; + m_widget->setGraphicsEffect(m_effect); + } + + void ChromeSnippet::enableEffect(bool enable) + { + if(m_effect) + m_effect->setEnabled(enable); + } + + void ChromeSnippet::toggleEffect() + { + if(m_effect) + m_effect->setEnabled(!m_effect->isEnabled()); + } + + void ChromeSnippet::moveBy(int dx, int dy) + { + m_widget->moveBy(dx,dy); + } + + QObject *ChromeSnippet::getGeometry() const { + + ScriptRectF *r = new ScriptRectF(m_widget->mapToScene(m_widget->rect()).boundingRect()); + // m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("rectf", r, QScriptEngine::ScriptOwnership); + return r; + } + + QObject *ChromeSnippet::childGeometry(const QString id) const { + QWebElement child = m_element.findFirst("#" + id); + if(child.isNull()) + return 0; + QRect childGeo = child.geometry(); + QRect parentGeo = m_element.geometry(); + //Return geometry relative to parent + return new ScriptRectF(QRect(childGeo.x()-parentGeo.x(), childGeo.y()-parentGeo.y(), childGeo.width(), childGeo.height())); + } + + void ChromeSnippet::onChromeComplete() { + + positionChildren(); + //If this snippet is linked to another (through 'LinkedTo' attribute, add as a link to that snippet + QString linkedTo = m_element.attribute("data-GinebraItemLinkedTo", "none" ); + if (linkedTo != "none") { + + ChromeSnippet * s = m_chrome->getSnippet(linkedTo); + if (s) { + s->addLink(this); + WebChromeItem * item = static_cast (widget()); + connect(item, SIGNAL(mouseEvent(QEvent::Type)), this, SIGNAL(snippetMouseEvent(QEvent::Type))); + + } + } + + } + + void ChromeSnippet::positionChildren() + { + QWebElementCollection children = m_element.findAll(".GinebraSnippet"); + foreach (QWebElement child, children) { + ChromeSnippet * childSnippet = m_chrome->getSnippet(child.attribute("id")); + QRect childGeo = child.geometry(); + QRect parentGeo = m_element.geometry(); + //Get child geometry relative to parent + QRectF childGeom(childGeo.x()-parentGeo.x(), childGeo.y()-parentGeo.y(), childGeo.width(), childGeo.height()); + qDebug() << "Parent geometry: " << parentGeo << " child geometry: " << childGeo; + childSnippet->widget()->setGeometry(childGeom); + } + + } + + void ChromeSnippet::addChild(ChromeSnippet * child) + { + qDebug() << "ChromeSnippet::addChild: " << child->elementId(); + QWebElement c = m_element.findFirst("#" + child->elementId()); + if(c.isNull()) + return; + QRect childGeo = c.geometry(); + QRect parentGeo = m_element.geometry(); + //Get child geometry relative to parent + QRectF childGeom(childGeo.x()-parentGeo.x(), childGeo.y()-parentGeo.y(), childGeo.width(), childGeo.height()); + child->widget()->setGeometry(childGeom); + child->widget()->setParentItem(widget()); + } + + QPointF ChromeSnippet::position() const { + //qDebug() << "Relative: " << m_widget->pos() << " Absolute : " << m_widget->mapToScene(m_widget->pos()); + //return m_widget->mapToScene(m_widget->pos()); + return m_widget->pos(); + } + + QObject *ChromeSnippet::getPosition() const { + ScriptPoint *result = new ScriptPoint(position().toPoint()); + //m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("point", result, QScriptEngine::ScriptOwnership); + return result; + } + + void ChromeSnippet::setPosition(int x, int y) + { + //qDebug() << "Requested x: " << x << " y: " << y; + //qDebug() << "Set position: " << m_widget->mapFromScene(QPointF(x,y)); + m_widget->setPos(QPointF(x,y)); + } + + void ChromeSnippet::anchorToView(const QString& view, const QString& where) + { + m_chrome->anchorToView(this, view); + } + + void ChromeSnippet::detachFromView(const QString& view, const QString& where) + { + m_chrome->detachFromView(this, view); + } + + void ChromeSnippet::anchorTo(const QString & id, int x, int y) + { + m_chrome->anchorTogether(this, id, x, y); + } + + void ChromeSnippet::unAnchor() + { + setAnchor("AnchorNone"); + m_chrome->unAnchor(this); + } + + QObject *ChromeSnippet::animate(int duration) { + GraphicsItemAnimation *an = new GraphicsItemAnimation(this, duration); + //m_owner->chromePage()->mainFrame()->addToJavaScriptWindowObject("animation", an, QScriptEngine::ScriptOwnership); + return an; + } + + void ChromeSnippet::setVisibilityAnimator(const QString& animator) + { + m_vAnimator = VisibilityAnimator::create(animator, this); + connect(m_vAnimator, SIGNAL(finished(bool)), this, SLOT(visibilityFinished(bool))); + } + + void ChromeSnippet::grabFocus() + { + qDebug() << "ChromeSnippet::grabFocus()"; + m_widget->setFocus(); + } + + int ChromeSnippet::zValue() + { + return m_widget->zValue(); + } + + void ChromeSnippet::setZValue(int z) + { + m_widget->setZValue(z); + } + + void ChromeSnippet::setTransform(QTransform transform) + { + m_widget->setTransform(transform); + } + + QTransform ChromeSnippet::transform() + { + return m_widget->transform(); + } + + void ChromeSnippet::addLink(ChromeSnippet * snippet) { + + m_links.append(snippet); + } + + void ChromeSnippet::dump() { + qDebug() << "ChromeSnippet::dump:" + << " id=" << elementId() + << " visible=" << isVisible() + << " zValue=" << zValue() + << " geometry=" << m_widget->mapToScene(m_widget->rect()).boundingRect(); + } +}