~smartboyhw/ubuntu/raring/calligra/2.6.0-0ubuntu1

« back to all changes in this revision

Viewing changes to stage/part/tools/animationtool/KPrAnimationsTimeLineView.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-10-23 21:09:16 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20121023210916-m82w6zxnxhaxz7va
Tags: 1:2.5.90-0ubuntu1
* New upstream alpha release (LP: #1070436)
  - Add libkactivities-dev and libopenimageio-dev to build-depends
  - Add kubuntu_build_calligraactive.diff to build calligraactive by default
  - Add package for calligraauthor and move files that are shared between
    calligrawords and calligraauthor to calligrawords-common
* Document the patches
* Remove numbers from patches so they follow the same naming scheme as
  the rest of our patches.
* calligra-data breaks replaces krita-data (<< 1:2.5.3) (LP: #1071686)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
 * Copyright (C) 2012 Paul Mendez <paulestebanms@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 "KPrAnimationsTimeLineView.h"
 
21
 
 
22
//Stage Headers
 
23
#include "KPrTimeLineHeader.h"
 
24
#include "KPrTimeLineView.h"
 
25
#include "KPrShapeAnimations.h"
 
26
#include "animations/KPrShapeAnimation.h"
 
27
#include "tools/animationtool/KPrAnimationGroupProxyModel.h"
 
28
 
 
29
//KDE HEADERS
 
30
 
 
31
 
 
32
//QT HEADERS
 
33
#include <QVBoxLayout>
 
34
#include <QHBoxLayout>
 
35
#include <QAbstractTableModel>
 
36
#include <QScrollArea>
 
37
#include <QPainter>
 
38
#include <QFontMetrics>
 
39
#include <QDebug>
 
40
#include <QScrollBar>
 
41
 
 
42
 
 
43
//default value for invalid columns and rows index
 
44
const int INVALID = -1;
 
45
 
 
46
//Max value for time scale
 
47
const int SCALE_LIMIT = 1000;
 
48
const int START_COLUMN = (int)KPrShapeAnimations::ShapeThumbnail;
 
49
const int END_COLUMN = (int)KPrShapeAnimations::StartTime;
 
50
 
 
51
KPrAnimationsTimeLineView::KPrAnimationsTimeLineView(QWidget *parent)
 
52
    : QWidget(parent)
 
53
    , m_model(0)
 
54
    , m_shapeModel(0)
 
55
    , m_selectedRow(INVALID)
 
56
    , m_selectedColumn(INVALID)
 
57
    , m_rowsHeigth(50)
 
58
    , m_stepsNumber(10)
 
59
    , m_scaleOversize(0)
 
60
    , m_maxLength(0.0)
 
61
{
 
62
    //Setup GUI
 
63
    m_view = new KPrTimeLineView(this);
 
64
    m_header = new KPrTimeLineHeader(this);
 
65
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
 
66
    m_scrollArea = new QScrollArea;
 
67
    m_scrollArea->setBackgroundRole(QPalette::Light);
 
68
    m_scrollArea->setWidget(m_view);
 
69
    m_scrollArea->installEventFilter(m_view);
 
70
    m_scrollArea->installEventFilter(m_header);
 
71
    QVBoxLayout *layout = new QVBoxLayout;
 
72
    layout->addWidget(m_header);
 
73
    layout->addWidget(m_scrollArea);
 
74
    layout->setContentsMargins(0, 0, 0, 0);
 
75
    layout->setSpacing(0);
 
76
    setLayout(layout);
 
77
 
 
78
    //Connect Signals
 
79
    connect(m_view, SIGNAL(clicked(const QModelIndex&)), this, SIGNAL(clicked(const QModelIndex&)));
 
80
    connect(m_view, SIGNAL(timeValuesChanged(QModelIndex)), this, SIGNAL(timeValuesChanged(QModelIndex)));
 
81
    connect(m_view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(requestContextMenu(QPoint)));
 
82
}
 
83
 
 
84
void KPrAnimationsTimeLineView::setModel(KPrAnimationGroupProxyModel *model)
 
85
{
 
86
    m_model = model;
 
87
    m_shapeModel = dynamic_cast<KPrShapeAnimations *>(model->sourceModel());
 
88
    Q_ASSERT(m_shapeModel);
 
89
    updateColumnsWidth();
 
90
    connect(m_shapeModel, SIGNAL(layoutChanged()), this, SLOT(updateColumnsWidth()));
 
91
    connect(m_shapeModel, SIGNAL(layoutChanged()), this, SLOT(resetData()));
 
92
    connect(m_shapeModel, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged()));
 
93
    connect(m_shapeModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(update()));
 
94
    //It works only if one item could be selected each time
 
95
    connect(m_shapeModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(notifyTimeValuesChanged(QModelIndex)));
 
96
    connect(m_shapeModel, SIGNAL(timeScaleModified()), this, SLOT(adjustScale()));
 
97
    adjustScale();
 
98
    m_header->update();
 
99
    m_view->update();
 
100
}
 
101
 
 
102
void KPrAnimationsTimeLineView::resizeEvent(QResizeEvent *event)
 
103
{
 
104
    if (m_scrollArea->horizontalScrollBar()) {
 
105
        connect(m_scrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)), m_header, SLOT(repaint()));
 
106
    }
 
107
    QWidget::resizeEvent(event);
 
108
}
 
109
 
 
110
KPrAnimationGroupProxyModel *KPrAnimationsTimeLineView::model()
 
111
{
 
112
    return m_model;
 
113
}
 
114
 
 
115
KPrShapeAnimations *KPrAnimationsTimeLineView::animationsModel()
 
116
{
 
117
    return m_shapeModel;
 
118
}
 
119
 
 
120
int KPrAnimationsTimeLineView::widthOfColumn(int column) const
 
121
{
 
122
    switch (column) {
 
123
    case KPrShapeAnimations::ShapeThumbnail:
 
124
        return rowsHeigth() * 3 / 2;
 
125
    case KPrShapeAnimations::AnimationIcon:
 
126
        return rowsHeigth() * 5 / 4;
 
127
    case KPrShapeAnimations::StartTime:
 
128
        return 2 * (rowsHeigth() * 2 / 3 + rowsHeigth() * 10 / 4 + 10);
 
129
    default:
 
130
        return 0;
 
131
    }
 
132
    return 0;
 
133
}
 
134
 
 
135
void KPrAnimationsTimeLineView::setSelectedRow(int row)
 
136
{
 
137
    m_selectedRow = row;
 
138
    m_view->update();
 
139
}
 
140
 
 
141
void KPrAnimationsTimeLineView::setSelectedColumn(int column)
 
142
{
 
143
    m_selectedColumn = column;
 
144
}
 
145
 
 
146
QModelIndex KPrAnimationsTimeLineView::currentIndex()
 
147
{
 
148
    return m_model->index(m_selectedRow, m_selectedColumn, QModelIndex());
 
149
}
 
150
 
 
151
void KPrAnimationsTimeLineView::setCurrentIndex(const QModelIndex &index)
 
152
{
 
153
    setSelectedRow(index.row());
 
154
    setSelectedColumn(index.column());
 
155
    m_scrollArea->ensureVisible(widthOfColumn(index.row()),
 
156
                                rowsHeigth() * index.row());
 
157
}
 
158
 
 
159
int KPrAnimationsTimeLineView::rowsHeigth() const
 
160
{
 
161
    return m_rowsHeigth;
 
162
}
 
163
 
 
164
int KPrAnimationsTimeLineView::totalWidth() const
 
165
{
 
166
    int width = 0;
 
167
    for (int i = 0; i < KPrShapeAnimations::Duration; i++){
 
168
        width = width + widthOfColumn(i);
 
169
    }
 
170
    return width;
 
171
}
 
172
 
 
173
void KPrAnimationsTimeLineView::paintItemBorder(QPainter *painter, const QPalette &palette, const QRect &rect)
 
174
{
 
175
    painter->setPen(QPen(palette.button().color().darker(), 0.33));
 
176
    painter->drawLine(rect.bottomLeft(), rect.bottomRight());
 
177
    painter->drawLine(rect.bottomRight(), rect.topRight());
 
178
}
 
179
 
 
180
QScrollArea *KPrAnimationsTimeLineView::scrollArea() const
 
181
{
 
182
    return m_scrollArea;
 
183
}
 
184
 
 
185
int KPrAnimationsTimeLineView::numberOfSteps() const
 
186
{
 
187
    return m_stepsNumber;
 
188
}
 
189
 
 
190
void KPrAnimationsTimeLineView::setNumberOfSteps(int steps)
 
191
{
 
192
    m_stepsNumber = steps;
 
193
}
 
194
 
 
195
void KPrAnimationsTimeLineView::incrementScale(int step)
 
196
{
 
197
    if ((numberOfSteps() + step) < SCALE_LIMIT) {
 
198
        setNumberOfSteps(numberOfSteps() + step);
 
199
        m_header->update();
 
200
        m_view->update();
 
201
    }
 
202
}
 
203
 
 
204
void KPrAnimationsTimeLineView::changeStartLimit(const int row)
 
205
{
 
206
    // If user wants a after_previous animation start before previous animation switch to with_previous
 
207
    QModelIndex index = m_model->index(row, 0);
 
208
    if (index.isValid()) {
 
209
        QModelIndex sourceIndex = m_model->mapToSource(index);
 
210
        m_shapeModel->recalculateStart(sourceIndex);
 
211
    }
 
212
}
 
213
 
 
214
void KPrAnimationsTimeLineView::adjustScale()
 
215
{
 
216
    m_maxLength = 10;
 
217
    for (int row = 0; row < m_model->rowCount(); ++ row){
 
218
        int startOffSet = calculateStartOffset(row);
 
219
        qreal length = m_model->data(m_model->index(row, KPrShapeAnimations::StartTime)).toInt() +
 
220
                m_model->data(m_model->index(row,KPrShapeAnimations:: Duration)).toInt() + startOffSet;
 
221
        length = length / 1000;
 
222
        if (length > m_maxLength) {
 
223
            m_maxLength = length;
 
224
        }
 
225
    }
 
226
    const int spacing = 2;
 
227
    // Increment Scale if maxLength is out of range
 
228
    if ((m_maxLength + spacing * stepsScale()) > (numberOfSteps())) {
 
229
        incrementScale(m_maxLength + spacing * stepsScale() - numberOfSteps());
 
230
        m_header->update();
 
231
    }
 
232
    // Decrement scale if maxLength is too short
 
233
    if ((m_maxLength - spacing * stepsScale()) < (numberOfSteps())) {
 
234
        incrementScale(m_maxLength + spacing * stepsScale() - numberOfSteps());
 
235
        m_header->update();
 
236
    }
 
237
}
 
238
 
 
239
void KPrAnimationsTimeLineView::notifyTimeValuesChanged(const QModelIndex &index)
 
240
{
 
241
    QModelIndex newIndex = m_model->mapFromSource(index);
 
242
    emit timeValuesChanged(newIndex);
 
243
}
 
244
 
 
245
void KPrAnimationsTimeLineView::requestContextMenu(QPoint pos)
 
246
{
 
247
    emit customContextMenuRequested(m_view->mapToParent(pos));
 
248
}
 
249
 
 
250
int KPrAnimationsTimeLineView::stepsScale()
 
251
{
 
252
    // Set step size depending on the scale length
 
253
    int stepsNumber = numberOfSteps();
 
254
    if (stepsNumber < 15)
 
255
        return 1;
 
256
    else if (stepsNumber < 50)
 
257
        return 2;
 
258
    else if (stepsNumber < 100)
 
259
        return 5;
 
260
    else if (stepsNumber < 200)
 
261
        return 10;
 
262
    else if (stepsNumber < 300)
 
263
        return 20;
 
264
    else if (stepsNumber < 500)
 
265
        return 25;
 
266
    else
 
267
        return 60;
 
268
}
 
269
 
 
270
qreal KPrAnimationsTimeLineView::maxLineLength() const
 
271
{
 
272
    return m_maxLength;
 
273
}
 
274
 
 
275
void KPrAnimationsTimeLineView::setMaxLineLength(qreal length)
 
276
{
 
277
    if (length > 0) {
 
278
        m_maxLength = length;
 
279
    }
 
280
}
 
281
 
 
282
QColor KPrAnimationsTimeLineView::barColor(int row)
 
283
{
 
284
    Q_ASSERT(m_model);
 
285
    KPrShapeAnimation::PresetClass type =
 
286
            static_cast<KPrShapeAnimation::PresetClass>(m_model->data(m_model->index(row, KPrShapeAnimations::AnimationClass)).toInt());
 
287
    switch (type) {
 
288
        case KPrShapeAnimation::Entrance: return Qt::darkGreen;
 
289
        case KPrShapeAnimation::Emphasis: return Qt::blue;
 
290
        case KPrShapeAnimation::Custom: return Qt::gray;
 
291
        case KPrShapeAnimation::Exit: return Qt::red;
 
292
        default: return Qt::gray;
 
293
    }
 
294
}
 
295
 
 
296
int KPrAnimationsTimeLineView::calculateStartOffset(int row) const
 
297
{
 
298
    //calculate real start
 
299
    KPrShapeAnimation::NodeType triggerEvent = static_cast<KPrShapeAnimation::NodeType>(
 
300
               m_model->data(m_model->index(row, KPrShapeAnimations::NodeType)).toInt());
 
301
    if (row <= 0) {
 
302
        return 0;
 
303
    }
 
304
    if (triggerEvent == KPrShapeAnimation::AfterPrevious) {
 
305
        QModelIndex sourceIndex = m_model->mapToSource(m_model->index(row - 1, KPrShapeAnimations::NodeType));
 
306
        return m_shapeModel->animationEnd(sourceIndex);
 
307
    }
 
308
    if (triggerEvent == KPrShapeAnimation::WithPrevious) {
 
309
        QModelIndex sourceIndex = m_model->mapToSource(m_model->index(row - 1, KPrShapeAnimations::NodeType));
 
310
        return m_shapeModel->animationStart(sourceIndex);
 
311
    }
 
312
    return 0;
 
313
}
 
314
 
 
315
int KPrAnimationsTimeLineView::rowCount() const
 
316
{
 
317
    if (m_model) {
 
318
        return m_model->rowCount();
 
319
    }
 
320
    return 0;
 
321
}
 
322
 
 
323
QSize KPrAnimationsTimeLineView::sizeHint() const
 
324
{
 
325
    return QSize(m_view->sizeHint().width(), m_view->sizeHint().height() + m_header->sizeHint().height());
 
326
}
 
327
 
 
328
int KPrAnimationsTimeLineView::startColumn() const
 
329
{
 
330
    return START_COLUMN;
 
331
}
 
332
 
 
333
int KPrAnimationsTimeLineView::endColumn() const
 
334
{
 
335
    return END_COLUMN;
 
336
}
 
337
 
 
338
void KPrAnimationsTimeLineView::update()
 
339
{
 
340
    m_view->update();
 
341
    m_view->updateGeometry();
 
342
    this->updateGeometry();
 
343
    m_header->update();
 
344
    QWidget::update();
 
345
}
 
346
 
 
347
void KPrAnimationsTimeLineView::updateColumnsWidth()
 
348
{
 
349
    for (int row = 0; row < m_model->rowCount(); ++ row){
 
350
        qreal length = m_model->data(m_model->index(row, KPrShapeAnimations::StartTime)).toDouble() +
 
351
                m_model->data(m_model->index(row, KPrShapeAnimations::Duration)).toDouble();
 
352
        if (length > m_maxLength) {
 
353
            m_maxLength = length;
 
354
        }
 
355
    }
 
356
    m_view->setMinimumSize(m_view->minimumSizeHint());
 
357
}
 
358
 
 
359
void KPrAnimationsTimeLineView::resetData()
 
360
{
 
361
    m_selectedRow = INVALID;
 
362
    m_selectedColumn = INVALID;
 
363
    update();
 
364
}