ginebra2/ContentToolbarChromeItem.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
child 5 0f2326c2a325
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ginebra2/ContentToolbarChromeItem.cpp	Tue May 04 12:39:35 2010 +0300
@@ -0,0 +1,567 @@
+/*
+* 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 "ContentToolbarChromeItem.h"
+#include "GWebContentView.h"
+#include "mostvisitedsnippet.h"
+
+#include <QTimeLine>
+#include <QDebug>
+
+#define TOOLBAR_MARGIN 4
+#define TOOBAR_ANIMATION_DURATION 200
+#define TOOBAR_INACTIVITY_DURATION 5000
+
+namespace GVA {
+
+  ToolbarFadeAnimator::ToolbarFadeAnimator(): m_timeLine(NULL) 
+  {
+  }
+
+
+  ToolbarFadeAnimator::~ToolbarFadeAnimator() {
+
+    if (m_timeLine)
+      delete m_timeLine;
+  }
+
+  void ToolbarFadeAnimator::start(bool visible) {
+    //qDebug() << __PRETTY_FUNCTION__ << visible;
+    if (!m_timeLine) {
+      m_timeLine = new QTimeLine(TOOBAR_ANIMATION_DURATION);
+      connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(valueChange(qreal)));
+      connect(m_timeLine, SIGNAL(finished()), this, SIGNAL(finished()));
+    }
+    else {
+      m_timeLine->stop();
+    }
+    if (!visible) {
+      m_timeLine->setDirection(QTimeLine::Forward);
+
+    }
+    else {
+      m_timeLine->setDirection(QTimeLine::Backward);
+
+    }
+    m_timeLine->start();
+
+  }
+
+  void ToolbarFadeAnimator::stop() {
+
+    //qDebug() << __PRETTY_FUNCTION__ ;
+    m_timeLine->stop();
+  }
+
+  void ToolbarFadeAnimator::valueChange(qreal step) {
+    qreal value = step - 0.25;
+    value =  (value > 0)? value: 0.0;
+    emit  updateVisibility(value);
+  }
+
+  ContentToolbarChromeItem::ContentToolbarChromeItem(QGraphicsItem* parent)
+      : ToolbarChromeItem(parent), 
+      m_background(NULL),
+      m_middleSnippet(NULL),
+      m_bgopacity(0.75),
+      m_state(CONTENT_TOOLBAR_STATE_FULL),
+      m_inactiveTimerState(CONTENT_TOOLBAR_INACTIVITY_TIMER_NONE)
+  {
+
+    m_inactivityTimer = new QTimer(this);
+    connect(m_inactivityTimer, SIGNAL(timeout()), this, SLOT(onInactivityTimer()));
+
+    m_animator = new ToolbarFadeAnimator();
+    connect(m_animator, SIGNAL(updateVisibility(qreal)), this, SLOT(onUpdateVisibility(qreal)));
+    connect(m_animator, SIGNAL(finished()), this, SLOT(onAnimFinished()));
+
+    setFlags(QGraphicsItem::ItemDoesntPropagateOpacityToChildren);
+   
+  }
+
+  ContentToolbarChromeItem::~ContentToolbarChromeItem()
+  {
+    if (m_background ) 
+        delete m_background;
+    delete m_inactivityTimer;
+    delete m_animator;
+
+  }
+
+  void ContentToolbarChromeItem::resizeEvent(QGraphicsSceneResizeEvent * ev)
+  {
+    //qDebug() << __PRETTY_FUNCTION__ << boundingRect();
+    ToolbarChromeItem::resizeEvent(ev);
+    addFullBackground();
+ 
+  }
+
+  void ContentToolbarChromeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt, QWidget* widget)
+  {
+    Q_UNUSED(opt)
+    Q_UNUSED(widget)
+
+//    qDebug() << __PRETTY_FUNCTION__ << m_state;
+    painter->save();
+ 
+    painter->setRenderHint(QPainter::Antialiasing);
+ 
+    painter->setPen(pen());
+    painter->setOpacity(m_bgopacity);
+ 
+    switch (m_state) {
+        case CONTENT_TOOLBAR_STATE_PARTIAL:
+          ToolbarChromeItem::paint(painter, opt, widget);
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+          ToolbarChromeItem::paint(painter, opt, widget);
+        case CONTENT_TOOLBAR_STATE_FULL:
+          // fill path with color
+          painter->fillPath(*m_background,QBrush(grad()));
+          painter->drawPath(*m_background);
+          break;
+        default:
+          qDebug() << "ContentToolbarChromeItem::paint invalid state" ;
+          break;
+    }
+    // restore painter
+    painter->restore(); 
+ 
+  }
+
+
+  void ContentToolbarChromeItem::setSnippet(WebChromeContainerSnippet* snippet) {
+
+    //qDebug() << __func__ << snippet;
+    ToolbarChromeItem::setSnippet(snippet);
+
+    connect(snippet->chrome(), SIGNAL(chromeComplete()), this, SLOT(onChromeComplete()));
+    connect(snippet, SIGNAL(snippetMouseEvent(QEvent::Type)), this, SLOT(onSnippetMouseEvent(QEvent::Type)));
+    
+  }
+
+  void ContentToolbarChromeItem::onWebViewMouseEvents(QEvent::Type type) {
+
+//    qDebug() << __PRETTY_FUNCTION__ << type;
+    switch (type ) {
+      case QEvent::GraphicsSceneMousePress:
+      case QEvent::GraphicsSceneMouseDoubleClick:
+        handleMousePress();
+        break;
+      case QEvent::GraphicsSceneMouseRelease:
+        handleMouseRelease();
+        break;
+      default:
+        break;
+
+    }
+   
+  }
+
+  void ContentToolbarChromeItem::onSnippetMouseEvent( QEvent::Type type) {
+
+    
+//    qDebug() << __PRETTY_FUNCTION__ << type;
+    // Handle the snippet mouse events when we are in webview
+    if ( getSnippet()->chrome()->currentView() == "webView") {
+
+      if (type == QEvent::MouseButtonPress || type ==  QEvent::GraphicsSceneMousePress) {
+  
+        m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_NONE;
+        switch (m_state) {
+          case CONTENT_TOOLBAR_STATE_PARTIAL:
+            changeState(CONTENT_TOOLBAR_STATE_ANIM_TO_FULL);
+            break;
+          case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+            // Stop animation and change to full immediately
+            m_animator->stop();
+            changeState(CONTENT_TOOLBAR_STATE_FULL, false);
+            break;
+          case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+            // Do nothing here - will reset inactivity timer when
+            // animation completes
+            break;
+          case CONTENT_TOOLBAR_STATE_FULL:
+            resetInactivityTimer();
+            break;
+          default:
+            break;
+  
+        }
+      }
+      else if ( type == QEvent::MouseButtonRelease || type ==  QEvent::GraphicsSceneMouseRelease){
+        m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_ALLOWED;
+        if (m_state == CONTENT_TOOLBAR_STATE_FULL ){
+          resetInactivityTimer();
+        }
+      }
+    }
+  }
+
+  void ContentToolbarChromeItem::onChromeComplete() {
+
+    GWebContentView* webView  = static_cast<GWebContentView*> (getSnippet()->chrome()->getView("WebView"));
+    //qDebug() << __PRETTY_FUNCTION__ << webView;
+    if(webView){
+      connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
+      connect(webView, SIGNAL(loadStarted()), this, SLOT(onLoadStarted()));
+      connect(webView, SIGNAL(contentViewMouseEvent(QEvent::Type)) , this, SLOT(onWebViewMouseEvents(QEvent::Type)) );
+    }
+    // Get the middle snippet here for now
+    m_middleSnippet = getSnippet()->chrome()->getSnippet("ButtonContainer");
+    connect(m_middleSnippet, SIGNAL(snippetMouseEvent(QEvent::Type)), this, SLOT(onSnippetMouseEvent(QEvent::Type)));
+    QList <ChromeSnippet *> links = getSnippet()->links();
+    for (int i=0; i < links.count() ; i++) {
+
+      connect(links.at(i), SIGNAL(snippetMouseEvent(QEvent::Type)), this, SLOT(onSnippetMouseEvent(QEvent::Type)));
+
+    }
+
+    // Connect to shown and hidden signals to reset the inactivity timer
+    connect(getSnippet() , SIGNAL(shown()), this, SLOT(onSnippetHide()));
+    connect(getSnippet() , SIGNAL(hidden()), this, SLOT(onSnippetShow()));
+  }
+
+  void ContentToolbarChromeItem::onSnippetShow() {
+
+    // This is signal is received when the snippet is about to be hidden. So stop the timer
+    //qDebug() << __PRETTY_FUNCTION__; 
+    if (m_inactivityTimer->isActive() ) 
+        m_inactivityTimer->stop();
+  }
+
+  void ContentToolbarChromeItem::onSnippetHide() {
+
+    //qDebug() << __PRETTY_FUNCTION__; 
+    changeState(CONTENT_TOOLBAR_STATE_FULL, false);
+  }
+
+  void ContentToolbarChromeItem::onMVCloseComplete() {
+
+//    qDebug() << __PRETTY_FUNCTION__; 
+    ChromeSnippet * mv = getSnippet()->chrome()->getSnippet("MostVisitedViewId");
+    disconnect(mv, SIGNAL(mostVisitedSnippetCloseComplete()) , this, SLOT(onMVCloseComplete()));
+    // MostVisitedSnippet animation complete, so let's do toolbar animation
+    if (m_state == CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL) 
+      changeState(CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL, true);
+ 
+  }
+  
+  void ContentToolbarChromeItem::onLoadFinished(bool ok) {
+
+    Q_UNUSED(ok);
+    //qDebug() << __PRETTY_FUNCTION__ << m_state;
+    
+    // We should be in STATE_FULL when load completes as we would have 
+    // changed to  that state on starting a load
+    //assert(m_state == CONTENT_TOOLBAR_STATE_FULL)
+    m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_ALLOWED;
+    resetInactivityTimer();
+
+  }
+
+  void ContentToolbarChromeItem::onLoadStarted() {
+
+    //qDebug() << __PRETTY_FUNCTION__<< m_state; ;
+    m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_NONE;
+
+    switch (m_state) {
+      case CONTENT_TOOLBAR_STATE_PARTIAL:
+        changeState(CONTENT_TOOLBAR_STATE_FULL, false);
+        break;
+      case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+      case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+        // Stop animation and change to full immediately
+        m_animator->stop();
+        changeState(CONTENT_TOOLBAR_STATE_FULL, false);
+        break;
+      case CONTENT_TOOLBAR_STATE_FULL:
+        resetInactivityTimer();  
+        break;
+      default:
+        break;
+
+    }
+    //qDebug() << __PRETTY_FUNCTION__<< m_state; ;
+
+  }
+
+  void ContentToolbarChromeItem::onInactivityTimer() {
+
+    //assert(m_state == CONTENT_TOOLBAR_STATE_PARTIAL);
+    //qDebug() << __PRETTY_FUNCTION__ << m_state;
+    if (mvSnippetVisible()) {
+      changeState(CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL);
+      
+    }
+    else {
+      changeState(CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL, true);
+    }
+  }
+
+  void ContentToolbarChromeItem::onUpdateVisibility(qreal step) {
+
+    qreal value = 0.76 - step;
+    //qDebug() << __PRETTY_FUNCTION__ << step << value << m_bgopacity << opacity();
+    if (m_bgopacity != step ) {
+      m_bgopacity = step; 
+      getSnippet()->setOpacity(value);
+      m_middleSnippet->widget()->setOpacity(step);
+      update();
+    }
+  }
+
+  void ContentToolbarChromeItem::onAnimFinished() {
+
+    //qDebug() << __PRETTY_FUNCTION__ << m_state; 
+    switch (m_state) {
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+          changeState(CONTENT_TOOLBAR_STATE_PARTIAL);
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+          changeState(CONTENT_TOOLBAR_STATE_FULL, true);
+          break;
+        default:
+          break;
+  
+    }
+    //qDebug() << __PRETTY_FUNCTION__ << m_state; 
+    
+  }
+  void ContentToolbarChromeItem::addFullBackground() {
+
+    //qDebug() << __PRETTY_FUNCTION__ ;
+    qreal roundness((boundingRect().height() -TOOLBAR_MARGIN)/2);
+    QRectF r(1, 1, boundingRect().width()-TOOLBAR_MARGIN, boundingRect().height()-TOOLBAR_MARGIN);
+
+    if (m_background ) {
+        delete m_background;
+        m_background = NULL;
+    }
+    m_background = new QPainterPath();
+    m_background->addRoundedRect(r, roundness, roundness);
+  }
+
+  void ContentToolbarChromeItem::resetInactivityTimer() {
+
+//    qDebug()  << __PRETTY_FUNCTION__ << m_inactiveTimerState;
+    if (m_inactivityTimer->isActive() )
+        m_inactivityTimer->stop();
+    if (m_inactiveTimerState == CONTENT_TOOLBAR_INACTIVITY_TIMER_ALLOWED ) { 
+      m_inactivityTimer->start(TOOBAR_INACTIVITY_DURATION);
+    }
+  }
+
+  void ContentToolbarChromeItem::stateEnterFull(bool animate) {
+    
+    //qDebug() <<__PRETTY_FUNCTION__ ;
+    
+    resetInactivityTimer();
+    // Show the middle snippet and reset the opacity if we are here directly with no aniamtion
+    if (!animate) {
+      m_bgopacity = 0.75; 
+      m_middleSnippet->show();
+    }
+
+    m_state = CONTENT_TOOLBAR_STATE_FULL;
+    m_middleSnippet->widget()->setOpacity(1.0);
+    // TODO: specify the rect to be updated to avoid full repaint
+    update();
+  }
+
+  void ContentToolbarChromeItem::stateEnterPartial(bool animate) {
+
+    //qDebug() <<__PRETTY_FUNCTION__ ;
+    Q_UNUSED(animate);
+
+    // Explicity hide the linked snippets so that toggle button javascript gets the right
+    // signals that it is expecting
+    QList <ChromeSnippet *> links = getSnippet()->links();
+    for (int i=0; i < links.count() ; i++) {
+      //qDebug() << __PRETTY_FUNCTION__ << links.at(i)->elementId();
+      links.at(i)->hide();
+    }
+
+    m_middleSnippet->hide();
+    m_state = CONTENT_TOOLBAR_STATE_PARTIAL;
+    
+  }
+
+  void ContentToolbarChromeItem::stateEnterAnimToFull(bool animate) {
+
+    //qDebug() <<__PRETTY_FUNCTION__ ;
+    Q_UNUSED(animate);
+    m_state = CONTENT_TOOLBAR_STATE_ANIM_TO_FULL;
+    m_inactivityTimer->stop();
+    m_middleSnippet->show();
+    m_animator->start(false);
+    
+  }
+
+  void ContentToolbarChromeItem::stateEnterAnimToPartial(bool animate) {
+
+    //qDebug() <<__PRETTY_FUNCTION__ << animate ;
+    m_inactivityTimer->stop();
+    m_state = CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL;
+ 
+    if (animate ) {
+      m_animator->start(true);
+    }
+    else {
+
+      MostVisitedSnippet * mv = static_cast<MostVisitedSnippet *>(getSnippet()->chrome()->getSnippet("MostVisitedViewId")); 
+      connect(mv, SIGNAL(mostVisitedSnippetCloseComplete()) , this, SLOT(onMVCloseComplete()));
+      mv->close();
+    }
+    
+  }
+
+  void ContentToolbarChromeItem::changeState( ContentToolbarState state, bool animate){
+
+    onStateEntry(state, animate);
+  }
+
+  void ContentToolbarChromeItem::onStateEntry(ContentToolbarState state, bool animate){
+
+   //qDebug() << __PRETTY_FUNCTION__ ;
+   switch (state) {
+        case CONTENT_TOOLBAR_STATE_PARTIAL:
+          stateEnterPartial(animate);
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+          stateEnterAnimToFull(animate);
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+          stateEnterAnimToPartial(animate);
+          break;
+        case CONTENT_TOOLBAR_STATE_FULL:
+          stateEnterFull(animate);
+          break;
+        default:
+          qDebug() << "ContentToolbarChromeItem::onStateEntry -  invalid state" ;
+          break;
+    }
+  }
+
+  void ContentToolbarChromeItem::onStateExit(ContentToolbarState state){
+
+   //qDebug() << __PRETTY_FUNCTION__ ;
+   switch (state) {
+        case CONTENT_TOOLBAR_STATE_PARTIAL:
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+          break;
+        case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+          break;
+        case CONTENT_TOOLBAR_STATE_FULL:
+          break;
+        default:
+          qDebug() << "ContentToolbarChromeItem::onStateExit - invalid state" ;
+          break;
+    }
+  }
+
+  void ContentToolbarChromeItem::handleMousePress() {
+
+//    qDebug() << __PRETTY_FUNCTION__ << m_state;
+    m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_NONE;
+    switch (m_state) {
+      case CONTENT_TOOLBAR_STATE_PARTIAL:
+        changeState(CONTENT_TOOLBAR_STATE_ANIM_TO_FULL);
+        break;
+      case CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL:
+        // Stop animation and change to full immediately
+        m_animator->stop();
+        changeState(CONTENT_TOOLBAR_STATE_FULL, false);
+        break;
+      case CONTENT_TOOLBAR_STATE_ANIM_TO_FULL:
+        // Do nothing here - will reset inactivity timer when
+        // animation completes based on timer state then
+        break;
+      case CONTENT_TOOLBAR_STATE_FULL:
+        resetInactivityTimer();
+        break;
+      default:
+          qDebug() << "ContentToolbarChromeItem::handleMousePress invalid state" ;
+        break;
+ 
+    }
+
+    
+  }
+
+  void ContentToolbarChromeItem::handleMouseRelease() {
+
+//    qDebug() << __PRETTY_FUNCTION__ << m_state;
+    /* If in STATE_FULL, restart inactivity timer. In other states:
+     * STATE_PARTIAL, STATE_ANIM_TO_PARTIAL - not possible
+     * STATE_ANIM_TO_FULL - timer will be restarted on animation completion
+     */
+    
+    m_inactiveTimerState = CONTENT_TOOLBAR_INACTIVITY_TIMER_ALLOWED;
+    if (m_state == CONTENT_TOOLBAR_STATE_FULL ){
+      resetInactivityTimer();
+    }
+  }
+
+  bool ContentToolbarChromeItem::mvSnippetVisible() {
+
+    ChromeSnippet * mv = getSnippet()->chrome()->getSnippet("MostVisitedViewId"); 
+    bool result = false;
+   
+    if (mv && mv->isVisible() ) {
+      result = true;
+    }
+    return result;
+  }
+
+/*
+  //Not using this method now - potential performance hit 
+  void ContentToolbarChromeItem::changeState( ContentToolbarState state, bool animate){
+
+    if ( m_states[m_state].exitFunc ) {
+      
+      (*this.*(m_states[m_state].exitFunc))();
+    }
+    if (  m_states[state].enterFunc ) {
+      (*this.*(m_states[state].enterFunc))(animate);
+      
+    }
+
+  }
+ 
+  void ContentToolbarChromeItem::initStates() {
+
+
+    m_states[CONTENT_TOOLBAR_STATE_FULL].enterFunc = &ContentToolbarChromeItem::stateEnterFull;
+    m_states[CONTENT_TOOLBAR_STATE_FULL].exitFunc = NULL;
+
+    m_states[CONTENT_TOOLBAR_STATE_PARTIAL].enterFunc = &ContentToolbarChromeItem::stateEnterpartial;
+    m_states[CONTENT_TOOLBAR_STATE_PARTIAL].exitFunc = NULL;
+
+    m_states[CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL].enterFunc = &ContentToolbarChromeItem::stateEnterAnimToPartial;
+    m_states[CONTENT_TOOLBAR_STATE_ANIM_TO_PARTIAL].exitFunc = NULL;
+
+    m_states[CONTENT_TOOLBAR_STATE_ANIM_TO_FULL].enterFunc = &ContentToolbarChromeItem::stateEnterAnimToFull;
+    m_states[CONTENT_TOOLBAR_STATE_ANIM_TO_FULL].exitFunc = NULL;
+  }
+*/
+} // end of namespace GVA
+
+