-Added timeline
[dashstudio.git] / src / components / timeline / framestable.cpp
blobd3216e04290832348f14ab18ba8d54018999d18e
1 /***************************************************************************
2 * Copyright (C) 2005 by David Cuadrado *
3 * krawek@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "framestable.h"
23 #include <QPainter>
24 #include <QPaintEvent>
25 #include <QItemSelectionModel>
26 #include <QPainterPath>
27 #include <QScrollBar>
28 #include <QHeaderView>
30 #include "tlruler.h"
31 // #include "ktprojectrequest.h"
34 namespace Components {
36 ////////// FramesTableItemDelegate ///////////
38 class FramesTableItemDelegate : public QAbstractItemDelegate
40 public:
41 FramesTableItemDelegate(QObject * parent = 0 );
42 ~FramesTableItemDelegate();
43 virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
44 virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
47 FramesTableItemDelegate::FramesTableItemDelegate(QObject * parent) : QAbstractItemDelegate(parent)
51 FramesTableItemDelegate::~FramesTableItemDelegate()
55 void FramesTableItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
57 Q_ASSERT(index.isValid());
59 FramesTable *table = qobject_cast<FramesTable *>(index.model()->parent());
60 FramesTableItem *item = dynamic_cast<FramesTableItem *>(table->itemFromIndex(index));
62 QVariant value;
63 QStyleOptionViewItem opt = option;
65 // draw the background color
66 value = index.data( Qt::BackgroundColorRole );
68 if (value.isValid())
70 painter->save();
72 bool sound = table->isSoundLayer(index.row());
74 if( !sound )
76 painter->fillRect(option.rect, value.value<QColor>() );
78 else
82 painter->restore();
84 else
86 painter->save();
88 bool sound = table->isSoundLayer(index.row());
90 if( !sound )
92 if ( index.column() % 5 == 0 )
94 painter->fillRect(option.rect, Qt::lightGray );
96 else
98 painter->fillRect(option.rect, Qt::white );
101 else
105 painter->restore();
108 // Selection!
109 if (option.showDecorationSelected && (option.state & QStyle::State_Selected))
111 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
113 painter->save();
114 painter->setPen(QPen(option.palette.brush(cg, QPalette::Highlight), 3));
115 painter->drawRect(option.rect.adjusted(1,1,-2,-2));
116 painter->restore();
119 // Draw attributes
121 int offset = option.rect.width() - 2;
123 if ( item && index.isValid() )
125 if(item->isUsed() )
127 painter->save();
128 painter->setBrush(Qt::black);
130 if( !item->isSound() )
132 painter->drawEllipse( option.rect.left(), option.rect.bottom() - offset, offset, offset);
134 else
136 painter->setBrush(Qt::blue);
137 painter->drawRect( option.rect.left(), option.rect.bottom() - offset, offset, offset);
140 painter->restore();
143 if ( item->isLocked() )
145 painter->save();
146 painter->setBrush(Qt::red);
148 painter->drawEllipse( option.rect.left(), option.rect.bottom() - offset, offset, offset);
150 painter->restore();
155 QSize FramesTableItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
157 Q_ASSERT(index.isValid());
158 const QAbstractItemModel *model = index.model();
159 Q_ASSERT(model);
161 QVariant value = model->data(index, Qt::FontRole);
162 QFont fnt = value.isValid() ? qvariant_cast<QFont>(value) : option.font;
163 QString text = model->data(index, Qt::DisplayRole).toString();
164 QRect pixmapRect;
165 if (model->data(index, Qt::DecorationRole).isValid())
166 pixmapRect = QRect(0, 0, option.decorationSize.width(),
167 option.decorationSize.height());
169 QFontMetrics fontMetrics(fnt);
171 return (pixmapRect).size();
175 ////////// FramesTableItem ////////
177 FramesTableItem::FramesTableItem()
181 FramesTableItem::~FramesTableItem()
186 bool FramesTableItem::isUsed()
188 return data(IsUsed).toBool();
191 bool FramesTableItem::isLocked()
193 return data(IsLocked).toBool();
196 bool FramesTableItem::isSound()
198 QVariant data = this->data(IsSound);
200 if( data.canConvert<bool>() )
202 return data.toBool();
204 return false;
207 //// FramesTable
209 struct FramesTable::Private
211 struct LayerItem
213 LayerItem() : lastItem(-1), sound(false) {};
214 int lastItem;
215 bool sound;
218 int rectWidth, rectHeight;
219 QList<LayerItem> layers;
220 TLRuler *ruler;
223 FramesTable::FramesTable(QWidget *parent) : QTableWidget(0, 100, parent), d(new Private)
225 d->ruler = new TLRuler;
226 setup();
229 FramesTable::~FramesTable()
231 delete d;
234 void FramesTable::setup()
236 setItemDelegate( new FramesTableItemDelegate(this) );
238 setSelectionBehavior(QAbstractItemView::SelectItems);
239 setSelectionMode (QAbstractItemView::SingleSelection);
241 setHorizontalHeader(d->ruler);
242 connect(d->ruler, SIGNAL(logicalSectionSelected( int )), this, SLOT(emitFrameSelected( int )));
243 connect(this, SIGNAL(currentItemChanged( QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(emitFrameSelected(QTableWidgetItem *, QTableWidgetItem *)));
244 verticalHeader()->hide();
246 setItemSize( 10, 25 );
248 horizontalHeader()->setResizeMode(QHeaderView::Custom);
249 verticalHeader()->setResizeMode(QHeaderView::Custom);
254 void FramesTable::emitFrameSelected(int col)
256 selectColumn(col);
258 FramesTableItem *item = dynamic_cast<FramesTableItem *>(this->item(currentRow(), col));
260 if( item )
262 if( item->isUsed())
264 // emit frameRequest(KTProjectRequest::Select, this->column(item), verticalHeader()->visualIndex(this->row(item)), -1);
269 void FramesTable::emitFrameSelected(QTableWidgetItem *curr, QTableWidgetItem *prev)
271 FramesTableItem *item = dynamic_cast<FramesTableItem *>(curr);
273 if( item )
275 if( item->isUsed())
277 // emit frameRequest(KTProjectRequest::Select, this->column(item), verticalHeader()->visualIndex(this->row(item)), -1);
282 void FramesTable::setItemSize(int w, int h)
284 d->rectHeight = h;
285 d->rectWidth = w;
287 fixSize();
290 bool FramesTable::isSoundLayer(int row)
292 if( row < 0 && row >= d->layers.count() )
293 return false;
295 return d->layers[row].sound;
298 void FramesTable::insertLayer(int pos, const QString &name)
300 insertRow( pos );
302 Private::LayerItem layer;
303 layer.sound = false;
304 d->layers.insert(pos, layer);
306 // selectCell( pos, 0 );
308 fixSize();
311 void FramesTable::insertSoundLayer(int layerPos, const QString &name)
313 insertRow(layerPos);
315 Private::LayerItem layer;
316 layer.sound = true;
317 d->layers.insert(layerPos, layer);
319 fixSize();
322 void FramesTable::removeCurrentLayer()
324 int pos = verticalHeader()->logicalIndex(currentRow());
325 removeLayer(pos);
328 void FramesTable::removeLayer(int pos)
330 pos = verticalHeader()->logicalIndex(pos);
331 removeRow( pos );
332 d->layers.removeAt(pos);
335 void FramesTable::moveLayer(int position, int newPosition)
337 if ( position < 0 || position >= rowCount() || newPosition < 0 || newPosition >= rowCount() ) return;
339 blockSignals(true);
341 verticalHeader()->moveSection(position, newPosition);
343 blockSignals(false);
345 // FramesTableItem *item1 = takeItem(position, 0);
347 // bool up = true;
348 // if ( position > newPosition )
349 // {
350 // up = false; // down
351 // }
353 // if ( up )
354 // {
355 // for(int i = position+1; i <= newPosition; i++)
356 // {
357 // setItem(i-1, 0, takeItem(i, 0));
358 // }
359 // }
360 // else
361 // {
362 // for(int i = position-1; i >= newPosition; i-- )
363 // {
364 // setItem(i+1, 0, takeItem(i, 0));
365 // }
366 // }
368 // setItem(newPosition, 0, item1);
370 // setCurrentItem(item1);
373 int FramesTable::lastFrameByLayer(int layerPos)
375 int pos = verticalHeader()->logicalIndex(layerPos);
376 if ( pos < 0 || pos > d->layers.count() )
378 return -1;
380 return d->layers[pos].lastItem;
383 // FRAMES
386 void FramesTable::insertFrame(int layerPos, const QString &name)
388 if ( layerPos < 0 || layerPos >= d->layers.count() ) return;
390 layerPos = verticalHeader()->logicalIndex(layerPos);
392 d->layers[layerPos].lastItem++;
394 if ( d->layers[layerPos].lastItem >= columnCount() )
396 insertColumn( d->layers[layerPos].lastItem );
399 setAttribute( layerPos, d->layers[layerPos].lastItem, FramesTableItem::IsUsed, true);
400 setAttribute( layerPos, d->layers[layerPos].lastItem, FramesTableItem::IsSound, d->layers[layerPos].sound);
402 viewport()->update();
405 void FramesTable::setCurrentFrame(FramesTableItem *item)
407 setCurrentItem(item);
410 void FramesTable::setCurrentLayer(int layerPos)
412 setCurrentItem(item(verticalHeader()->logicalIndex(layerPos), 0));
415 void FramesTable::selectFrame(int index)
417 setCurrentItem( item( currentRow(), index ) );
420 void FramesTable::removeFrame(int layerPos, int position)
422 // for(int frameIndex = position; frameIndex < columnCount(); frameIndex++ )
423 // {
424 // setAttribute( layerPos, position, FramesTableItem::IsUsed, false);
425 // }
427 if ( layerPos < 0 || layerPos >= d->layers.count() )
429 return;
432 layerPos = verticalHeader()->logicalIndex(layerPos);
434 setAttribute( layerPos, d->layers[layerPos].lastItem, FramesTableItem::IsUsed, false );
436 d->layers[layerPos].lastItem--;
438 // viewport()->update( visualRect(indexFromItem( item(layerPos, position) )) );
439 viewport()->update();
442 void FramesTable::lockFrame(int layerPos, int position, bool lock)
444 if ( layerPos < 0 || layerPos >= d->layers.count() )
446 return;
449 layerPos = verticalHeader()->logicalIndex(layerPos);
451 setAttribute( layerPos, position, FramesTableItem::IsLocked, lock );
453 viewport()->update();
457 void FramesTable::setAttribute(int row, int col, FramesTableItem::Attributes att, bool value)
459 QTableWidgetItem *item = this->item(row, col);
461 if( !item )
463 item = new FramesTableItem;
464 setItem(row, col, item);
467 item->setData(att, value);
470 void FramesTable::fixSize()
472 for(int column = 0; column < columnCount(); column++)
474 horizontalHeader()->resizeSection(column, d->rectWidth);
476 for( int row = 0; row < rowCount(); row++)
478 verticalHeader()->resizeSection(row, d->rectHeight);
482 // void FramesTable::fixSectionMoved(int logical, int visual, int newVisual)
483 // {
484 // verticalHeader()->moveSection(newVisual, visual);
485 // }