ginebra2/ScrollableViewBase.cpp
author hgs
Tue, 29 Jun 2010 00:46:29 -0400
changeset 3 0954f5dd2cd0
child 16 3c88a81ff781
permissions -rw-r--r--
201026

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not,
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:
*
*/

#include "ScrollableViewBase.h"


#include "Kinetics/KineticScroller.h"

#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPointF>

namespace GVA {

ScrollableViewBase::ScrollableViewBase(QGraphicsItem* parent, Qt::WindowFlags wFlags)
    : QGraphicsWidget(parent, wFlags)
    , m_scrollWidget(0)
{
    //To get only the mouse events within the ScrollableViewBase.
    setFlag(QGraphicsItem::ItemClipsToShape, true);

    //To disable childrens painting outside the ViewportItem's rect.
    setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);

    //To speed up painting.
    setFlag(QGraphicsItem::ItemHasNoContents, true);
    setAttribute(Qt::WA_OpaquePaintEvent, true);

    m_kineticScroller = new KineticScroller(this);

    //Event filter on all children of the viewport, so that all mouse
    //events can be intercepted and used for kinetic scrolling.
    setFiltersChildEvents(true);
}

ScrollableViewBase::~ScrollableViewBase()
{}

void ScrollableViewBase::setWidget(QGraphicsWidget* view)
{
    if (view == m_scrollWidget)
        return;

    if (m_scrollWidget) {
        m_scrollWidget->setParentItem(0);
        delete m_scrollWidget;
    }

    m_scrollWidget = view;
    m_scrollWidget->setAttribute(Qt::WA_OpaquePaintEvent, true);
    m_scrollWidget->setParentItem(this);
}

QSize ScrollableViewBase::viewportSize() const
{
    return size().toSize();
}

QPoint ScrollableViewBase::maximumScrollPosition() const
{
    QSizeF contentsSize = m_scrollWidget->size();
    QSizeF viewportSize = size();
    QSize maxScrollSize = (contentsSize - viewportSize).toSize();

    return QPoint(qMax(0, maxScrollSize.width()), qMax(0, maxScrollSize.height()));
}

QPoint ScrollableViewBase::scrollPosition() const
{
    return (-scrollWidgetPos()).toPoint();
}

void ScrollableViewBase::setScrollPosition(const QPoint& pos, const QPoint& overShoot)
{
    m_overShoot = overShoot;
    setScrollWidgetPos(-pos);
}

void ScrollableViewBase::stateChanged(KineticScrollable::State oldState
                                      , KineticScrollable::State newState)
{
    Q_UNUSED(oldState);
    Q_UNUSED(newState);
}

void ScrollableViewBase::setScrollWidgetGeometry(const QRectF& geom)
{
    scrollWidget()->setGeometry(adjustScrollWidgetRect(geom));
}

QRectF ScrollableViewBase::adjustScrollWidgetRect(const QRectF& rect)
{
    //FIX ME : Stop animation of scroll widget before adjusting it here??
    QRectF newRect(rect);

    QSizeF widgetSize = rect.size();
    QSizeF viewportSize = size();

    qreal w = viewportSize.width() - widgetSize.width();
    qreal h = viewportSize.height() - widgetSize.height();

    if ( w > 0 ) {
        newRect.moveLeft(0);
        m_extraPos.setX(w/2);
      }
    else {
    	m_extraPos.setX(0);
        if (newRect.x() < w)
            newRect.moveLeft(w);
        if (newRect.x() > 0)
            newRect.moveLeft(0);
    }

    if ( h > 0 ) {
        m_extraPos.setY(h/2);
        newRect.moveTop(0);
      }
    else {
    	 m_extraPos.setY(0);
        if (newRect.y() < h)
            newRect.moveTop(h);
        if (newRect.y() > 0)
            newRect.moveTop(0);
    }
    //newRect.translate(m_extraPos);
    newRect.translate(m_overShoot);
    return newRect;
}

void ScrollableViewBase::setScrollWidgetPos(const QPointF& pos)
{
    setScrollWidgetGeometry(QRectF(pos, scrollWidget()->size()));
}

QPointF ScrollableViewBase::scrollWidgetPos() const
{
    return scrollWidget()->pos()  /*- m_extraPos*/ - m_overShoot;
}

} //namespace GVA