aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Gadomska <agadomsk@agadomska.(none)>2010-06-24 14:43:35 +0300
committerMike FABIAN <mike.fabian@basyskom.de>2010-06-29 15:58:18 +0200
commit6dac29bbf852283dfc1f7d684a1b22964ecb7024 (patch)
tree6a013eecb863f235610d0058a30c3a8a7b1b3c97
parent74fa5eaf7e73eb41042e4f8f3bc5037dbee3c299 (diff)
Changes: spinner animation view/animation reimplemented
RevBy: TrustMe
-rw-r--r--src/views/mspinnerview.cpp199
-rw-r--r--src/views/mspinnerview.h6
-rw-r--r--src/views/mspinnerview_p.h10
-rw-r--r--src/views/style/mspinnerstyle.h35
4 files changed, 147 insertions, 103 deletions
diff --git a/src/views/mspinnerview.cpp b/src/views/mspinnerview.cpp
index 52c636f2..eb88bc6f 100644
--- a/src/views/mspinnerview.cpp
+++ b/src/views/mspinnerview.cpp
@@ -21,6 +21,7 @@
#include <QTimeLine>
#include <QTimer>
#include <QGraphicsSceneResizeEvent>
+#include <QBitmap>
#include <math.h>
#include "mspinnerview.h"
@@ -43,8 +44,7 @@ const int SpinnerRefreshRate = 30;
MSpinnerViewPrivate::MSpinnerViewPrivate()
: q_ptr(0),
controller(0),
- inactiveElement(0),
- activeElement(0),
+ pieImage(0),
position(0),
elapsed(0),
timer(0)
@@ -54,9 +54,6 @@ MSpinnerViewPrivate::MSpinnerViewPrivate()
MSpinnerViewPrivate::~MSpinnerViewPrivate()
{
- MTheme::releasePixmap(activeElement);
- MTheme::releasePixmap(inactiveElement);
-
delete timer;
}
@@ -68,6 +65,11 @@ MSpinnerView::MSpinnerView(MProgressIndicator *controller) :
Q_D(MSpinnerView);
d->q_ptr = this;
d->controller = controller;
+
+ d->bgRect = QRect();
+ d->fgRect = QRect();
+ d->pieImage = new QPixmap();
+
connect(controller, SIGNAL(visibleChanged()), this, SLOT(visibilityChanged()));
}
@@ -82,19 +84,18 @@ void MSpinnerViewPrivate::animationTimeout()
Q_Q(MSpinnerView);
if (q->model()->unknownDuration()) {
-
- // calculate interval in secs and add it to elapsed time
- qreal interval = (qreal) timer->interval() / 1000.0;
+ //calculate interval in secs and add it to elapsed time
+ qreal interval = static_cast<qreal>(timer->interval() / 1000.0);
elapsed += interval;
- // calculate how many steps we should take
- int steps = (int)(elapsed * (qreal) q->style()->speed());
+ //calculate how many steps we should take
+ int steps = static_cast<int>(elapsed * (qreal) q->style()->speed());
if (steps > 0) {
- // subtract the amount we will step from the elapsed time
+ //subtract the amount we will step from the elapsed time
elapsed -= steps * (1.0 / (qreal) q->style()->speed());
- // and perform the stepping
- position = (position + steps) % elements.count();
- // redraw
+ //and perform the stepping
+ position = (position + steps) % 360;
+ //redraw
q->update();
}
}
@@ -115,16 +116,18 @@ void MSpinnerView::updateData(const QList<const char *>& modifications)
}
if (d->controller->isVisible())
d->timer->start(SpinnerRefreshRate);
- } else {
- delete d->timer;
- d->timer = NULL;
+ } else {
+ delete d->timer;
+ d->timer = NULL;
+ }
}
}
- }
+ applyStyle();
update();
}
+
void MSpinnerView::setupModel()
{
MWidgetView::setupModel();
@@ -143,109 +146,136 @@ void MSpinnerView::setupModel()
d->timer = NULL;
}
- update();
+ update();
}
-void MSpinnerView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
+void MSpinnerView::calculateSizes()
{
- Q_UNUSED(option);
+ Q_D(MSpinnerView);
+ QSize s;
+ //calculating sizes for background
+ if ( rect().toRect().height() >= rect().toRect().width() ) {
+ s = QSize(rect().toRect().width(), rect().toRect().width());
+ } else {
+ s = QSize(rect().toRect().height(), rect().toRect().height());
+ }
- Q_D(const MSpinnerView);
+ QPoint bgDrawPoint(size().width() * 0.5 - s.width() * 0.5, size().height() * 0.5 - s.height() * 0.5 );
- const int elementsCount = d->elements.count();
- if (style()->inactiveImage() && style()->activeImage()) {
+ d->bgRect = QRect(bgDrawPoint, s);
- // size of an element
- QSize size(style()->elementSize(), style()->elementSize());
+ //calculating foreground size:
+ d->fgRect = QRect(
+ QPoint((d->bgRect.topLeft().x() + style()->progressStripSize()), (d->bgRect.topLeft().y() + style()->progressStripSize())),
+ QPoint((d->bgRect.bottomRight().x() - style()->progressStripSize()), (d->bgRect.bottomRight().y() - style()->progressStripSize())));
- if (model()->unknownDuration()) {
- // every n'th should be active
- int span = (d->elements.count() / style()->activeElementCount());
- // this tells the active index within the span
- int activeIndexInSpan = d->position % span;
+ *d->pieImage = QPixmap(d->bgRect.size());
+ }
- // draw all elements with proper image
- for (int i = 0; i < elementsCount; ++i) {
- if ((i % span) == activeIndexInSpan) {
- painter->drawPixmap(QRect(d->elements[i], size), *style()->activeImage());
- } else {
- painter->drawPixmap(QRect(d->elements[i], size), *style()->inactiveImage());
- }
- }
- } else {
- // active element count
- int active = (model()->value() - model()->minimum()) * d->elements.count() /
- qMax(model()->maximum() - model()->minimum(), 1);
-
- // draw active elements
- for (int i = 0; i < active; ++i) {
- painter->drawPixmap(QRect(d->elements[i], size), *style()->activeImage());
- }
+void MSpinnerView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const
+{
+ Q_D(const MSpinnerView);
+ Q_UNUSED(option);
+ Q_UNUSED(painter);
- // draw inactive elements
- for (int i = active; i < elementsCount; ++i) {
- painter->drawPixmap(QRect(d->elements[i], size), *style()->inactiveImage());
- }
- }
- }
+ style()->bgImage()->draw(d->bgRect, painter);
}
-void MSpinnerViewPrivate::calculateShape(QSizeF size)
+void MSpinnerView::drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const
{
- Q_Q(MSpinnerView);
-
- QSizeF s = size - QSizeF(q->style()->elementSize(), q->style()->elementSize());
+ Q_UNUSED(option);
+ Q_UNUSED(painter);
- qreal diameter = qMin(s.width(), s.height());
+ /*previously drawing foreground was here, but it is drawing it incorrectly for some reason
+ drawing foreground is moved to drawContents temporary*/
+}
- // clear existing elements
- elements.clear();
+QRect centerScale( QRect const & r, double s )
+{
+ int w = r.width() * s;
+ int h = r.height() * s;
+ int x = r.x() + (r.width() - w)/2;
+ int y = r.y() + (r.height() - h)/2;
+ return QRect(x, y, w, h);
+}
- if (q->style()->elementCount() > 0) {
- // center point
- QPoint center(size.width() * 0.5, size.height() * 0.5);
+void MSpinnerView::createPieImage( int startAngle, int endAngle, QSize const & size, QPixmap const & image ) const
+{
+ Q_D(const MSpinnerView);
+ d->pieImage->rect().setSize( size );
+ d->pieImage->fill( Qt::transparent);
- // radius for the spinner
- qreal radius = diameter * 0.5f;
+ QPainter piePainter( d->pieImage );
+ piePainter.setBrush( QBrush(image) );
+ piePainter.setPen( QPen(Qt::transparent) );
- // half element size
- qreal halfElementSize = q->style()->elementSize() * 0.5;
+ // Qt starts at 3:00 and goes CCW, we provide values starting at 12:00 and going CW
+ piePainter.drawPie( centerScale(QRect(QPoint(),size), 1.5),
+ (90-endAngle)*16,
+ (endAngle-startAngle)*16 );
+}
- qreal angle = 0;
- qreal span = (M_PI * 2.0) / q->style()->elementCount();
+void MSpinnerView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
+{
+ Q_UNUSED(option);
- // calculate spherical shape and store points where the item should be drawn
- const int elementsCount = q->style()->elementCount();
- for (int i = 0; i < elementsCount; ++i) {
+ Q_D(const MSpinnerView);
- QPoint position;
- position.setX(center.x() + (sinf(angle) * radius) - halfElementSize);
- position.setY(center.y() - (cosf(angle) * radius) - halfElementSize);
+ // Temporary: these should be made as style parameters
+ static int const minScale = 75; // scale used for minimum size when growing/shrinking
+ static int const maxScale = 100; // maybe not needed as style
+ static int const sweepAngle = 90; // sweep angle for unknown duration
+ static int const resolution = 100; // number of divisions in circle for unknown duration mode
+
+ // calculated values input into rendering
+ double startAngle = 0.0;
+ double endAngle = 0.0;
+ double scale = 1.0;
+
+ // Calculate values depending on mode
+ if ( model()->unknownDuration() ) {
+ startAngle = d->position * 360/resolution;
+ endAngle = startAngle + sweepAngle;
+ scale = 1.0;
+ }
+ else {
+ startAngle = 0.0;
+ endAngle = 360*(model()->value() - model()->minimum()) / (model()->maximum() - model()->minimum());
- elements.append(position);
+ double growAngle = 1; //can be adjusted if grow/shrink animation for not uknown duration required
+ double angleIncrement = (maxScale-minScale)/growAngle; // conversion from angle to scale
- angle += span;
- }
+ scale = endAngle < growAngle ? minScale + endAngle * angleIncrement :
+ endAngle > 360-growAngle ? minScale + (360-endAngle) * angleIncrement : maxScale;
+ scale /= 100.0;
}
+
+ // Render the image
+ createPieImage( startAngle, endAngle, d->bgRect.size(), *style()->progressImage()->pixmap() );
+ d->pieImage->setMask( style()->maskImage()->pixmap()->createHeuristicMask() );
+ painter->drawPixmap( scale > .99 ? d->bgRect : centerScale(d->bgRect, scale), *d->pieImage, d->pieImage->rect() );
+
+ //drawing foreground here, because there's something wrong with drawForeground()
+ style()->fgImage()->draw( d->fgRect, painter);
}
void MSpinnerView::resizeEvent(QGraphicsSceneResizeEvent *event)
{
- Q_D(MSpinnerView);
- d->calculateShape(event->newSize());
+ MWidgetView::resizeEvent(event);
+ calculateSizes();
}
void MSpinnerView::applyStyle()
{
- Q_D(MSpinnerView);
- MWidgetView::applyStyle();
- d->calculateShape(size());
+ MWidgetView::applyStyle();
+ calculateSizes();
}
void MSpinnerViewPrivate::visibilityChanged()
{
+ Q_Q(MSpinnerView);
if (timer) {
if (controller->isVisible()) {
timer->start(SpinnerRefreshRate);
@@ -253,6 +283,7 @@ void MSpinnerViewPrivate::visibilityChanged()
timer->stop();
}
}
+ q->calculateSizes();
}
#include "moc_mspinnerview.cpp"
diff --git a/src/views/mspinnerview.h b/src/views/mspinnerview.h
index 2ec95bed..670c5a0d 100644
--- a/src/views/mspinnerview.h
+++ b/src/views/mspinnerview.h
@@ -82,6 +82,9 @@ public:
protected:
//! \reimp
virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
+ virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
+ virtual void drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const;
+
void resizeEvent(QGraphicsSceneResizeEvent *event);
virtual void setupModel();
virtual void applyStyle();
@@ -94,6 +97,9 @@ protected slots:
//! \reimp_end
private:
+ void calculateSizes();
+ void createPieImage( int startAngle, int endAngle, QSize const & size, QPixmap const & image ) const;
+
Q_DISABLE_COPY(MSpinnerView)
Q_DECLARE_PRIVATE(MSpinnerView)
diff --git a/src/views/mspinnerview_p.h b/src/views/mspinnerview_p.h
index db5e0219..399bee2a 100644
--- a/src/views/mspinnerview_p.h
+++ b/src/views/mspinnerview_p.h
@@ -22,6 +22,7 @@
#include <QObject>
#include <QPointF>
+#include <QRect>
class MStyle;
class MProgressIndicator;
@@ -42,17 +43,18 @@ public:
void animationTimeout();
void visibilityChanged();
- void calculateShape(QSizeF size);
MProgressIndicator *controller;
+ mutable QPixmap *pieImage;
- const QPixmap *inactiveElement;
- const QPixmap *activeElement;
int position;
qreal elapsed;
QTimer *timer;
- QVector<QPoint> elements;
+
+ QRect bgRect;
+ QRect fgRect;
+
#ifdef M_UNIT_TEST
M_UNIT_TEST;
diff --git a/src/views/style/mspinnerstyle.h b/src/views/style/mspinnerstyle.h
index 2211899d..f17e9f0b 100644
--- a/src/views/style/mspinnerstyle.h
+++ b/src/views/style/mspinnerstyle.h
@@ -35,35 +35,40 @@ class M_EXPORT MSpinnerStyle : public MWidgetStyle
M_STYLE(MSpinnerStyle)
/*!
- \property MSpinnerStyle::activeImage
- \brief Image of the active bar element.
+ \property MSpinnerStyle::fgImage
+ \brief Image of foreground of spinner
*/
- M_STYLE_PTR_ATTRIBUTE(QPixmap *, activeImage, ActiveImage)
+ M_STYLE_PTR_ATTRIBUTE(MScalableImage*, fgImage, FgImage)
/*!
- \property MSpinnerStyle::inactiveImage
- \brief Image of the inactive bar element.
+ \property MSpinnerStyle:bgImage
+ \brief Image of background of spinner
*/
- M_STYLE_PTR_ATTRIBUTE(QPixmap *, inactiveImage, InactiveImage)
+ M_STYLE_PTR_ATTRIBUTE(MScalableImage *, bgImage, BgImage)
/*!
- \property MSpinnerStyle::speed
- \brief Speed of unknown duration progress animation (distance/sec).
+ \property MSpinnerStyle::maskImage
+ \brief Image of mask for spinner background
*/
- M_STYLE_ATTRIBUTE(int, speed, Speed)
+ M_STYLE_PTR_ATTRIBUTE(MScalableImage *, maskImage, MaskImage)
/*!
- \property MSpinnerStyle::activeElementCount
- \brief The number of active elements in circular progress indicator (unknown duration).
+ \property MSpinnerStyle::progressImage
+ \brief Image of progress bar for spinner
*/
- M_STYLE_ATTRIBUTE(int, activeElementCount, ActiveElementCount)
+ M_STYLE_PTR_ATTRIBUTE(MScalableImage *, progressImage, ProgressImage)
/*!
- \property MSpinnerStyle::elementSize
- \brief Size of an element in the circle.
+ \property MSpinnerStyle::progressStripSize
+ \brief Size of the strip of progress indicator.
*/
- M_STYLE_ATTRIBUTE(qreal, elementSize, ElementSize)
+ M_STYLE_ATTRIBUTE(qreal, progressStripSize, ProgressStripSize)
+ /*!
+ \property MSpinnerStyle::speed
+ \brief Speed of unknown duration progress animation (distance/sec).
+ */
+ M_STYLE_ATTRIBUTE(int, speed, Speed)
/*!
\property MSpinnerStyle::elementCount