18 #include "timelinecells.h"
21 #include <QResizeEvent>
22 #include <QMouseEvent>
26 #include "layermanager.h"
27 #include "playbackmanager.h"
28 #include "preferencemanager.h"
29 #include "toolmanager.h"
32 TimeLineCells::TimeLineCells(
TimeLine* parent,
Editor* editor, TIMELINE_CELL_TYPE type ) : QWidget( parent )
36 mPrefs = editor->preference();
41 frameLength = mPrefs->getInt(SETTING::TIMELINE_SIZE);
42 fontSize = mPrefs->getInt(SETTING::LABEL_FONT_SIZE);
43 frameSize = mPrefs->getInt(SETTING::FRAME_SIZE);
44 shortScrub = mPrefs->isOn(SETTING::SHORT_SCRUB);
45 drawFrameNumber = mPrefs->isOn(SETTING::DRAW_LABEL);
50 startLayerNumber = -1;
56 setMinimumSize( 500, 4 * layerHeight );
57 setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ) );
58 setAttribute( Qt::WA_OpaquePaintEvent,
false );
60 connect( mPrefs, &PreferenceManager::optionChanged,
this, &TimeLineCells::loadSetting );
63 TimeLineCells::~TimeLineCells()
65 if ( m_pCache )
delete m_pCache;
68 void TimeLineCells::loadSetting(SETTING setting)
72 case SETTING::TIMELINE_SIZE:
73 frameLength = mPrefs->getInt(SETTING::TIMELINE_SIZE);
74 timeLine->updateLength();
76 case SETTING::LABEL_FONT_SIZE:
77 fontSize = mPrefs->getInt(SETTING::LABEL_FONT_SIZE);
79 case SETTING::FRAME_SIZE:
80 frameSize = mPrefs->getInt(SETTING::FRAME_SIZE);
81 timeLine->updateLength();
83 case SETTING::SHORT_SCRUB:
84 shortScrub = mPrefs->isOn(SETTING::SHORT_SCRUB);
86 case SETTING::DRAW_LABEL:
87 drawFrameNumber = mPrefs->isOn(SETTING::DRAW_LABEL);
95 int TimeLineCells::getFrameNumber(
int x )
97 int frameNumber = frameOffset + 1 + ( x - m_offsetX ) / frameSize;
101 int TimeLineCells::getFrameX(
int frameNumber )
103 int x = m_offsetX + ( frameNumber - frameOffset ) * frameSize;
107 int TimeLineCells::getLayerNumber(
int y )
109 int layerNumber = layerOffset + ( y - m_offsetY ) / layerHeight;
113 if (layerNumber <= mEditor->
object()->getLayerCount())
114 layerNumber = mEditor->object()->getLayerCount() - 1 - layerNumber;
123 if ( layerNumber >= mEditor->object()->getLayerCount() )
125 layerNumber = mEditor->object()->getLayerCount();
139 int TimeLineCells::getLayerY(
int layerNumber )
142 return m_offsetY + ( mEditor->object()->getLayerCount() - 1 - layerNumber - layerOffset )*layerHeight;
145 void TimeLineCells::updateFrame(
int frameNumber )
147 int x = getFrameX( frameNumber );
148 update( x - frameSize, 0, frameSize + 1, height() );
151 void TimeLineCells::updateContent()
157 void TimeLineCells::drawContent()
159 if ( m_pCache == NULL )
161 m_pCache =
new QPixmap( size() );
162 if ( m_pCache->isNull() )
169 QPainter painter( m_pCache );
171 Object*
object = mEditor->object();
173 Q_ASSERT_X(
object !=
nullptr,
"",
"" );
175 Layer* layer =
object->getLayer( mEditor->layers()->currentLayerIndex() );
176 if ( layer == NULL )
return;
179 painter.setPen( Qt::NoPen );
180 painter.setBrush( Qt::lightGray );
181 painter.drawRect( QRect( 0, 0, width(), height() ) );
184 for (
int i = 0; i <
object->getLayerCount(); i++ )
186 if ( i != mEditor->layers()->currentLayerIndex() )
188 Layer* layeri =
object->getLayer( i );
189 if ( layeri != NULL )
193 case TIMELINE_CELL_TYPE::Tracks:
194 layeri->paintTrack( painter,
this, m_offsetX,
195 getLayerY( i ), width() - m_offsetX,
196 getLayerHeight(),
false, frameSize );
199 case TIMELINE_CELL_TYPE::Layers:
200 layeri->paintLabel( painter,
this, 0,
201 getLayerY( i ), width() - 1,
202 getLayerHeight(),
false, mEditor->allLayers() );
208 if ( abs( getMouseMoveY() ) > 5 )
210 if ( m_eType == TIMELINE_CELL_TYPE::Tracks )
212 layer->paintTrack( painter,
this, m_offsetX, getLayerY( mEditor->layers()->currentLayerIndex() ) + getMouseMoveY(), width() - m_offsetX, getLayerHeight(),
true, frameSize );
214 if ( m_eType == TIMELINE_CELL_TYPE::Layers )
216 layer->paintLabel( painter,
this, 0, getLayerY( mEditor->layers()->currentLayerIndex() ) + getMouseMoveY(), width() - 1, getLayerHeight(),
true, mEditor->allLayers() );
218 painter.setPen( Qt::black );
219 painter.drawRect( 0, getLayerY( getLayerNumber( endY ) ) - 1, width(), 2 );
223 if ( m_eType == TIMELINE_CELL_TYPE::Tracks )
225 layer->paintTrack( painter,
228 getLayerY( mEditor->layers()->currentLayerIndex() ),
234 if ( m_eType == TIMELINE_CELL_TYPE::Layers )
236 layer->paintLabel( painter,
239 getLayerY( mEditor->layers()->currentLayerIndex() ),
243 mEditor->allLayers() );
248 painter.setPen( Qt::NoPen );
249 painter.setBrush( QColor( 220, 220, 220 ) );
250 painter.drawRect( QRect( 0, 0, width() - 1, m_offsetY - 1 ) );
251 painter.setPen( Qt::gray );
252 painter.drawLine( 0, 0, width() - 1, 0 );
253 painter.drawLine( 0, m_offsetY - 2, width() - 1, m_offsetY - 2 );
254 painter.setPen( Qt::lightGray );
255 painter.drawLine( 0, m_offsetY - 3, width() - 1, m_offsetY - 3 );
256 painter.drawLine( 0, 0, 0, m_offsetY - 3 );
258 if ( m_eType == TIMELINE_CELL_TYPE::Layers )
261 painter.setPen( Qt::black );
262 if ( mEditor->allLayers() == 0 ) { painter.setBrush( Qt::NoBrush ); }
263 if ( mEditor->allLayers() == 1 ) { painter.setBrush( Qt::darkGray ); }
264 if ( mEditor->allLayers() == 2 ) { painter.setBrush( Qt::black ); }
265 painter.setRenderHint( QPainter::Antialiasing,
true );
266 painter.drawEllipse( 6, 4, 9, 9 );
267 painter.setRenderHint( QPainter::Antialiasing,
false );
269 else if ( m_eType == TIMELINE_CELL_TYPE::Tracks )
272 painter.setPen( QColor( 70, 70, 70, 255 ) );
273 painter.setBrush( Qt::darkGray );
274 painter.setFont( QFont(
"helvetica", 10 ) );
276 int fps = mEditor->playback()->fps();
277 for (
int i = frameOffset; i < frameOffset + ( width() - m_offsetX ) / frameSize; i++ )
279 incr = ( i < 9 ) ? 4 : 0;
281 if(i + 1 >= timeLine->getRangeLower() && i < timeLine->getRangeUpper())
283 painter.setPen( Qt::NoPen );
284 painter.setBrush( Qt::yellow );
286 painter.drawRect( getFrameX( i ), 1, frameSize + 1, 2 );
288 painter.setPen( QColor( 70, 70, 70, 255 ) );
289 painter.setBrush( Qt::darkGray );
294 painter.drawLine( getFrameX( i ), 1, getFrameX( i ), 5 );
296 else if ( i%fps == fps / 2 )
298 painter.drawLine( getFrameX( i ), 1, getFrameX( i ), 5 );
302 painter.drawLine( getFrameX( i ), 1, getFrameX( i ), 3 );
304 if ( i == 0 || i%fps == fps - 1 )
306 painter.drawText( QPoint( getFrameX( i ) + incr, 15 ), QString::number( i + 1 ) );
311 painter.setPen( Qt::darkGray );
312 painter.drawLine( 0, 0, 0, height() );
316 void TimeLineCells::paintOnionSkin( QPainter& painter )
318 Layer* layer = mEditor->layers()->currentLayer();
319 if (layer ==
nullptr) {
323 int frameNumber = mEditor->currentFrame();
325 int prevOnionSkinCount = mEditor->preference()->getInt(SETTING::ONION_PREV_FRAMES_NUM);
326 int nextOnionSkinCount = mEditor->preference()->getInt(SETTING::ONION_NEXT_FRAMES_NUM);
328 bool isAbsolute = (mEditor->preference()->getString(SETTING::ONION_TYPE) ==
"absolute");
330 if (mEditor->preference()->isOn(SETTING::PREV_ONION) && prevOnionSkinCount > 0) {
333 int onionFrameNumber = layer->getPreviousFrameNumber(frameNumber, isAbsolute);
334 int onionPosition = 0;
336 while (onionPosition < prevOnionSkinCount && onionFrameNumber > 0)
338 painter.setBrush( QColor( 128, 128, 128, 128 ) );
339 painter.setPen( Qt::NoPen );
341 onionRect.setTopLeft( QPoint( getFrameX( onionFrameNumber - 1 ), 0 ) );
342 onionRect.setBottomRight( QPoint( getFrameX( onionFrameNumber ), height() ) );
343 onionRect.setBottomRight( QPoint( getFrameX( onionFrameNumber ), 19 ) );
344 painter.drawRect( onionRect );
346 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, isAbsolute);
351 if (mEditor->preference()->isOn(SETTING::NEXT_ONION) && nextOnionSkinCount > 0) {
353 int onionFrameNumber = layer->getNextFrameNumber(frameNumber, isAbsolute);
354 int onionPosition = 0;
356 while (onionPosition < nextOnionSkinCount && onionFrameNumber > 0)
358 painter.setBrush( QColor( 128, 128, 128, 128 ) );
359 painter.setPen( Qt::NoPen );
361 onionRect.setTopLeft( QPoint( getFrameX( onionFrameNumber - 1 ), 0 ) );
362 onionRect.setBottomRight( QPoint( getFrameX( onionFrameNumber ), height() ) );
363 onionRect.setBottomRight( QPoint( getFrameX( onionFrameNumber ), 19 ) );
364 painter.drawRect( onionRect );
366 onionFrameNumber = layer->getNextFrameNumber(onionFrameNumber, isAbsolute);
372 void TimeLineCells::paintEvent( QPaintEvent* event )
376 Object*
object = mEditor->object();
377 Layer* layer = mEditor->layers()->currentLayer();
379 Q_ASSUME(
object !=
nullptr && layer !=
nullptr );
381 QPainter painter(
this );
383 bool isPlaying = mEditor->playback()->isPlaying();
384 if ( ( !isPlaying && !timeLine->scrubbing ) || m_pCache == NULL )
390 painter.drawPixmap( QPoint( 0, 0 ), *m_pCache );
393 if ( m_eType == TIMELINE_CELL_TYPE::Tracks )
396 paintOnionSkin(painter);
400 if ( mEditor->currentFrame() > frameOffset )
402 painter.setBrush( QColor( 255, 0, 0, 128 ) );
403 painter.setPen( Qt::NoPen );
404 painter.setFont( QFont(
"helvetica", 10 ) );
407 scrubRect.setTopLeft( QPoint( getFrameX( mEditor->currentFrame() - 1 ), 0 ) );
408 scrubRect.setBottomRight( QPoint( getFrameX( mEditor->currentFrame() ), height() ) );
411 scrubRect.setBottomRight( QPoint( getFrameX( mEditor->currentFrame() ), 19 ) );
413 painter.drawRect( scrubRect );
414 painter.setPen( QColor( 70, 70, 70, 255 ) );
416 if ( mEditor->currentFrame() < 10 )
421 painter.drawText( QPoint( getFrameX( mEditor->currentFrame() - 1 ) + incr, 15 ),
422 QString::number( mEditor->currentFrame() ) );
427 void TimeLineCells::resizeEvent( QResizeEvent* event )
432 emit lengthChanged( getFrameLength() );
435 void TimeLineCells::mousePressEvent( QMouseEvent* event )
437 if ( primaryButton != Qt::NoButton )
return;
438 int frameNumber = getFrameNumber( event->pos().x() );
439 int layerNumber = getLayerNumber( event->pos().y() );
441 startY =
event->pos().y();
442 startLayerNumber = layerNumber;
443 endY =
event->pos().y();
445 startFrameNumber = frameNumber;
446 lastFrameNumber = startFrameNumber;
448 canMoveFrame =
false;
449 movingFrames =
false;
451 canBoxSelect =
false;
452 boxSelecting =
false;
454 clickSelecting =
false;
456 primaryButton =
event->button();
458 mEditor->tools()->currentTool()->switchingLayers();
461 case TIMELINE_CELL_TYPE::Layers:
462 if ( layerNumber != -1 && layerNumber < mEditor->
object()->getLayerCount() )
464 if ( event->pos().x() < 15 )
466 mEditor->switchVisibilityOfLayer( layerNumber );
470 mEditor->layers()->setCurrentLayer( layerNumber );
473 if ( layerNumber == -1 )
475 if ( event->pos().x() < 15 )
477 mEditor->toggleShowAllLayers();
481 case TIMELINE_CELL_TYPE::Tracks:
482 if ( event->button() == Qt::MidButton )
484 lastFrameNumber = getFrameNumber( event->pos().x() );
488 if ( frameNumber == mEditor->currentFrame() && ( !shortScrub || ( shortScrub && startY < 20 ) ) )
490 if (mEditor->playback()->isPlaying())
492 mEditor->playback()->stop();
494 timeLine->scrubbing =
true;
498 if ( ( layerNumber != -1 ) && layerNumber < mEditor->
object()->getLayerCount() )
500 int previousLayerNumber = mEditor->layers()->currentLayerIndex();
502 if (previousLayerNumber != layerNumber) {
503 Layer *previousLayer = mEditor->object()->getLayer(previousLayerNumber);
504 previousLayer->deselectAll();
506 mEditor->setCurrentLayer( layerNumber );
509 Layer *currentLayer = mEditor->object()->getLayer(layerNumber);
514 if (event->modifiers() == Qt::AltModifier) {
518 clickSelecting =
true;
521 currentLayer->selectAllFramesAfter(frameNumber);
526 else if (!currentLayer->isFrameSelected(frameNumber)) {
531 clickSelecting =
true;
533 if ( event->modifiers() == Qt::ControlModifier ) {
535 currentLayer->toggleFrameSelected(frameNumber,
true);
537 else if ( event->modifiers() == Qt::ShiftModifier ) {
539 currentLayer->extendSelectionTo(frameNumber);
542 currentLayer->toggleFrameSelected(frameNumber,
false);
552 currentLayer->mousePress( event, frameNumber );
553 timeLine->updateContent();
557 if ( frameNumber > 0 )
559 if (mEditor->playback()->isPlaying())
561 mEditor->playback()->stop();
564 mEditor->scrubTo( frameNumber );
566 timeLine->scrubbing =
true;
567 qDebug(
"Scrub to %d frame", frameNumber );
576 void TimeLineCells::mouseMoveEvent( QMouseEvent* event )
578 if ( m_eType == TIMELINE_CELL_TYPE::Layers )
580 endY =
event->pos().y();
581 emit mouseMovedY( endY - startY );
583 int frameNumber = getFrameNumber( event->pos().x() );
586 if ( m_eType == TIMELINE_CELL_TYPE::Tracks )
588 if ( primaryButton == Qt::MidButton )
591 frameOffset = qMin( qMax( 0, frameLength - width() / getFrameSize() ), qMax( 0, frameOffset + lastFrameNumber - frameNumber ) );
593 emit offsetChanged( frameOffset );
597 if ( timeLine->scrubbing )
599 mEditor->scrubTo( frameNumber );
603 if ( startLayerNumber != -1 && startLayerNumber < mEditor->
object()->getLayerCount() )
605 Layer *currentLayer = mEditor->object()->getLayer(startLayerNumber);
609 if ( frameNumber != lastFrameNumber ) {
613 if ( canMoveFrame ) {
619 int offset = frameNumber - lastFrameNumber;
620 currentLayer->moveSelectedFrames(offset);
622 mEditor->updateCurrentFrame();
625 else if ( canBoxSelect ){
631 currentLayer->deselectAll();
632 currentLayer->setFrameSelected(startFrameNumber,
true);
633 currentLayer->extendSelectionTo(frameNumber);
636 lastFrameNumber = frameNumber;
639 currentLayer->mouseMove( event, frameNumber );
647 void TimeLineCells::mouseReleaseEvent( QMouseEvent* event )
649 qDebug(
"TimeLineCell: mouse release event." );
650 if ( event->button() != primaryButton )
return;
652 primaryButton = Qt::NoButton;
654 emit mouseMovedY( 0 );
655 timeLine->scrubbing =
false;
656 int frameNumber = getFrameNumber( event->pos().x() );
657 if ( frameNumber < 1 ) frameNumber = -1;
658 int layerNumber = getLayerNumber( event->pos().y() );
659 if ( m_eType == TIMELINE_CELL_TYPE::Tracks && primaryButton != Qt::MidButton && layerNumber != -1 && layerNumber < mEditor->
object()->getLayerCount() )
661 Layer *currentLayer = mEditor->object()->getLayer(layerNumber);
663 if (!timeLine->scrubbing && !movingFrames && !clickSelecting && !boxSelecting ) {
667 if ( event->modifiers() == Qt::ControlModifier ) {
669 currentLayer->toggleFrameSelected(frameNumber,
true);
672 currentLayer->toggleFrameSelected(frameNumber,
false);
676 currentLayer->mouseRelease( event, frameNumber );
678 if ( m_eType == TIMELINE_CELL_TYPE::Layers && layerNumber != startLayerNumber && startLayerNumber != -1 && layerNumber != -1 )
680 mEditor->moveLayer( startLayerNumber, layerNumber );
682 timeLine->updateContent();
685 void TimeLineCells::mouseDoubleClickEvent( QMouseEvent* event )
687 int frameNumber = getFrameNumber( event->pos().x() );
688 int layerNumber = getLayerNumber( event->pos().y() );
691 if ( event->pos().y() < 20 )
693 mPrefs->set(SETTING::SHORT_SCRUB, !shortScrub);
697 Layer* layer = mEditor->object()->getLayer( layerNumber );
700 if ( m_eType == TIMELINE_CELL_TYPE::Tracks && ( layerNumber != -1 ) && ( frameNumber > 0 ) && layerNumber < mEditor->
object()->getLayerCount() )
702 mEditor->object()->getLayer( layerNumber )->mouseDoubleClick( event, frameNumber );
704 else if ( m_eType == TIMELINE_CELL_TYPE::Layers )
706 layer->editProperties();
712 void TimeLineCells::hScrollChange(
int x )
718 void TimeLineCells::vScrollChange(
int x )
724 void TimeLineCells::setMouseMoveY(
int x )