1 /////////////////////////////////////////////////////////////////////////
4 // Copyright(C) 2009 Igor Trindade Oliveira <igor.oliveira@indt.org.br>//
5 // Copyright(C) 2009 Adenilson Cavalcanti <adenilson.silva@idnt.org.br>//
7 // This library is free software; you can redistribute it and/or //
8 // modify it under the terms of the GNU Lesser General Public //
9 // License as published by the Free Software Foundation; either //
10 // version 2.1 of the License, or (at your option) any later version. //
12 // This library is distributed in the hope that it will be useful, //
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
15 // Lesser General Public License for more details. //
17 // You should have received a copy of the GNU Lesser General Public //
18 // License along with this library; if not, write to the Free Software //
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
21 /////////////////////////////////////////////////////////////////////////
22 #include "kineticview.h"
23 #include "scrollbar.h"
27 #include <QGraphicsGridLayout>
29 #include <QPropertyAnimation>
33 * - fix velocity( create a new easing curve? )
35 * - kinetic velocity parameterized upon count of list items
36 * - horizontal scrolling
37 * - parameterize dimensions
38 * - ringbuffer (minimize number of items in the QGV).
41 class KineticScrollingPrivate
44 KineticScrollingPrivate(): mScrollVelocity(0), timerID(0),
45 overshoot(40), bounceFlag(0)
50 t
= QTime::currentTime();
54 unsigned int elapsed()
59 void verticalScroll(int value
)
61 widget
->setPos(QPoint(0, -value
*10));
64 void horizontalScroll(int value
)
66 widget
->setPos(QPoint(-value
*10, 0));
69 /* Just for backport sake */
85 void mousePressEvent(QGraphicsSceneMouseEvent
*event
)
94 void mouseMoveEvent(QGraphicsSceneMouseEvent
*event
)
96 int temp
= event
->lastPos().y() - event
->pos().y();
103 void mouseReleaseEvent(QGraphicsSceneMouseEvent
*event
)
105 timeDelta
= elapsed();
106 int temp
= event
->lastPos().y() - event
->pos().y();
108 kin_movement
+= temp
;
110 if (timeDelta
> 200) {
111 if (kin_movement
> 0)
118 void wheelReleaseEvent(QGraphicsSceneWheelEvent
*event
)
120 timeDelta
= elapsed();
121 int temp
= event
->delta();
123 kin_movement
+= temp
;
125 /* Just for backport sake */
127 unsigned int timeDelta
;
128 qreal scrollVelocity
;
132 qreal mScrollVelocity
;
133 enum { None
, Up
, Down
};
134 int timerID
, overshoot
, cposition
, direction
, minimalPos
, maximumPos
;
137 QGraphicsWidget
*widget
;
138 QGraphicsWidget
*scrollingWidget
;
144 KineticView::KineticView(QGraphicsWidget
*parent
)
145 : QGraphicsWidget(parent
)
147 d
= new KineticScrollingPrivate
;
148 setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Expanding
);
149 d
->scrollingWidget
= new QGraphicsWidget(this);
150 d
->scrollingWidget
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Expanding
);
151 d
->scrollingWidget
->setFlag(QGraphicsItem::ItemClipsChildrenToShape
, true);
152 layout
= new QGraphicsGridLayout(this);
153 layout
->addItem(d
->scrollingWidget
, 0, 0);
155 verticalScrollbar
= new ScrollBar(this);
156 connect(verticalScrollbar
, SIGNAL(valueChanged(int)), this, SLOT(setVerticalScrollValue(int)));
157 layout
->addItem(verticalScrollbar
, 0, 1);
159 setAcceptedMouseButtons(Qt::LeftButton
);
162 KineticView::~KineticView()
166 delete scrollAnimation
;
169 void KineticView::adjustScrollBar()
171 verticalScrollbar
->setMaximum( qMax( 0,
172 int( d
->widget
->size().height() - d
->scrollingWidget
->size().height())));
175 void KineticView::setWidget(QGraphicsWidget
*item
)
178 d
->widget
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Fixed
);
179 d
->widget
->setParentItem(d
->scrollingWidget
);
180 d
->widget
->setPos(0, 0);
181 d
->widget
->setAcceptedMouseButtons(Qt::LeftButton
);
183 scrollAnimation
= new QPropertyAnimation(d
->widget
, "geometry");
184 connect(scrollAnimation
, SIGNAL(finished()), this, SLOT(overshoot()));
185 scrollAnimation
->setEasingCurve(QEasingCurve::OutCirc
);
191 void KineticView::overshoot()
193 qDebug() << "animation is over...";
196 void KineticView::setVerticalScrollValue(int value
)
198 d
->widget
->setPos(0, -value
);
201 void KineticView::mousePressEvent(QGraphicsSceneMouseEvent
*event
)
203 if (scrollAnimation
->state() != QAbstractAnimation::Stopped
)
204 scrollAnimation
->stop();
207 d
->mousePressEvent(event
);
210 void KineticView::mouseMoveEvent(QGraphicsSceneMouseEvent
*event
)
212 d
->mouseMoveEvent(event
);
213 setVerticalScrollValue(-(d
->widget
->pos().y() - d
->normalMovement()));
214 QGraphicsWidget::mouseMoveEvent(event
);
217 int KineticView::thresholdPosition(int value
)
220 int minimalPos
= -d
->widget
->size().height() + d
->scrollingWidget
->size().height();
221 minimalPos
= qMin( 0, minimalPos
);
222 int maximumPos
= value
;
224 int cposition
= qBound( minimalPos
, maximumPos
, 0);
229 void KineticView::resetAnimation(int duration
)
231 if (scrollAnimation
->state() != QAbstractAnimation::Stopped
)
232 scrollAnimation
->stop();
233 QRectF tmpGeometry
= d
->widget
->geometry();
234 scrollAnimation
->setStartValue(tmpGeometry
);
235 int position
= thresholdPosition(tmpGeometry
.y() - d
->kinMovement()*6);
236 tmpGeometry
.setY(position
);
237 scrollAnimation
->setEndValue(tmpGeometry
);
238 scrollAnimation
->setEndValue(tmpGeometry
);
239 scrollAnimation
->setDuration(duration
);
240 scrollAnimation
->start();
243 void KineticView::mouseReleaseEvent(QGraphicsSceneMouseEvent
*event
)
246 d
->mouseReleaseEvent(event
);
247 resetAnimation(d
->duration()*8);
251 void KineticView::wheelEvent(QGraphicsSceneWheelEvent
*event
)
254 d
->mousePressEvent(NULL
);
255 d
->wheelReleaseEvent(event
);
259 void KineticView::resizeEvent(QGraphicsSceneResizeEvent
*event
)
263 QGraphicsWidget::resizeEvent(event
);