1 /* This file is part of the KDE project
2    Copyright (C) 2008 Sven Langkamp <sven.langkamp@gmail.com>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #include "KPrSideFanWipeStrategy.h"
21 
22 #include <math.h>
23 #include <QWidget>
24 #include <QPainter>
25 #include <QPainterPath>
26 
27 #include "KPrClockWipeSubpathHelper.h"
28 
KPrSideFanWipeStrategy(int positionAngle,int fanCount,int subType,const char * smilType,const char * smilSubType,bool reverse)29 KPrSideFanWipeStrategy::KPrSideFanWipeStrategy(int positionAngle, int fanCount, int subType, const char * smilType, const char *smilSubType, bool reverse )
30     : KPrPageEffectStrategy( subType, smilType, smilSubType, reverse ), m_fanCount(fanCount)
31 {
32     m_positionAngle = static_cast<double>(positionAngle)/180 * M_PI;
33     m_startAngle = static_cast<double>(positionAngle)/180 * M_PI + M_PI;
34 }
35 
~KPrSideFanWipeStrategy()36 KPrSideFanWipeStrategy::~KPrSideFanWipeStrategy()
37 {
38 }
39 
setup(const KPrPageEffect::Data & data,QTimeLine & timeLine)40 void KPrSideFanWipeStrategy::setup( const KPrPageEffect::Data &data, QTimeLine &timeLine )
41 {
42     Q_UNUSED(data);
43     timeLine.setFrameRange( 0, 180 );
44 }
45 
paintStep(QPainter & p,int currPos,const KPrPageEffect::Data & data)46 void KPrSideFanWipeStrategy::paintStep( QPainter &p, int currPos, const KPrPageEffect::Data &data )
47 {
48     int width = data.m_widget->width();
49     int height = data.m_widget->height();
50     QRect rect( 0, 0, width, height );
51     p.drawPixmap( QPoint( 0, 0 ), data.m_oldPage, rect );
52 
53     QPoint center(width/2, height/2);
54 
55     for(int i = 0; i < m_fanCount; i++) {
56 
57         double fanAnglePositionAngle = m_positionAngle + 2*M_PI/m_fanCount*i;
58         QPoint rotationCenter(center.x() + width/2*qRound(cos(fanAnglePositionAngle)),
59                               center.y() - height/2*qRound(sin(fanAnglePositionAngle)));
60 
61         double fanAngle = fanAnglePositionAngle + M_PI;
62         double angle = static_cast<double>(currPos)/90 * 0.25*M_PI;
63 
64         QRect boundingRect;
65         if(m_fanCount > 1) {
66             boundingRect = rect;
67             boundingRect.translate(rotationCenter.x() - center.x(), rotationCenter.y() - center.y());
68         }
69         else {
70             boundingRect = QRect( 0, 0, width + 2*abs(rotationCenter.x() - center.x()), height + 2*abs(rotationCenter.y() - center.y() ));
71             boundingRect.moveCenter(rotationCenter);
72         }
73 
74         QPainterPath clipPath;
75         if(reverse()) {
76             KPrClockWipeSubpathHelper::addSubpathForCircularArc(&clipPath, boundingRect, fanAngle - 0.5*M_PI, fanAngle - 0.5*M_PI + angle);
77             KPrClockWipeSubpathHelper::addSubpathForCircularArc(&clipPath, boundingRect, fanAngle + 0.5*M_PI - angle, fanAngle + 0.5*M_PI);
78             p.setClipPath(clipPath);
79             p.drawPixmap( rect.intersected(boundingRect), data.m_newPage, rect.intersected(boundingRect) );
80         }
81         else {
82             KPrClockWipeSubpathHelper::addSubpathForCircularArc(&clipPath, boundingRect, fanAngle - angle, fanAngle + angle);
83             p.setClipPath(clipPath);
84             p.drawPixmap( rect.intersected(boundingRect), data.m_newPage, rect.intersected(boundingRect) );
85         }
86     }
87 }
88 
next(const KPrPageEffect::Data & data)89 void KPrSideFanWipeStrategy::next( const KPrPageEffect::Data &data )
90 {
91     data.m_widget->update();
92 }
93