18 #include "timelinecells.h"
20 #include <QApplication>
21 #include <QResizeEvent>
22 #include <QInputDialog>
26 #include "camerapropertiesdialog.h"
29 #include "layermanager.h"
31 #include "playbackmanager.h"
32 #include "preferencemanager.h"
34 #include "toolmanager.h"
36 TimeLineCells::TimeLineCells(
TimeLine* parent,
Editor* editor, TIMELINE_CELL_TYPE type) :
QWidget(parent)
40 mPrefs = editor->preference();
43 mFrameLength = mPrefs->getInt(SETTING::TIMELINE_SIZE);
44 mFontSize = mPrefs->getInt(SETTING::LABEL_FONT_SIZE);
45 mFrameSize = mPrefs->getInt(SETTING::FRAME_SIZE);
46 mbShortScrub = mPrefs->isOn(SETTING::SHORT_SCRUB);
47 mDrawFrameNumber = mPrefs->isOn(SETTING::DRAW_LABEL);
53 connect(mPrefs, &PreferenceManager::optionChanged,
this, &TimeLineCells::loadSetting);
56 TimeLineCells::~TimeLineCells()
61 void TimeLineCells::loadSetting(SETTING setting)
65 case SETTING::TIMELINE_SIZE:
66 mFrameLength = mPrefs->getInt(SETTING::TIMELINE_SIZE);
67 mTimeLine->updateLength();
69 case SETTING::LABEL_FONT_SIZE:
70 mFontSize = mPrefs->getInt(SETTING::LABEL_FONT_SIZE);
72 case SETTING::FRAME_SIZE:
73 mFrameSize = mPrefs->getInt(SETTING::FRAME_SIZE);
74 mTimeLine->updateLength();
76 case SETTING::SHORT_SCRUB:
77 mbShortScrub = mPrefs->isOn(SETTING::SHORT_SCRUB);
79 case SETTING::DRAW_LABEL:
80 mDrawFrameNumber = mPrefs->isOn(SETTING::DRAW_LABEL);
88 int TimeLineCells::getFrameNumber(
int x)
const
90 int frameNumber = mFrameOffset + 1 + (x - mOffsetX) / mFrameSize;
94 int TimeLineCells::getFrameX(
int frameNumber)
const
96 int x = mOffsetX + (frameNumber - mFrameOffset) * mFrameSize;
100 void TimeLineCells::setFrameSize(
int size)
103 mPrefs->set(SETTING::FRAME_SIZE, mFrameSize);
107 int TimeLineCells::getLayerNumber(
int y)
109 int layerNumber = mLayerOffset + (y - mOffsetY) / mLayerHeight;
111 int totalLayerCount = mEditor->object()->getLayerCount();
115 if (layerNumber <= totalLayerCount)
116 layerNumber = (totalLayerCount - 1) - layerNumber;
125 if (layerNumber >= totalLayerCount)
127 layerNumber = totalLayerCount;
132 if (layerNumber < -1)
139 int TimeLineCells::getInbetweenLayerNumber(
int y) {
140 int layerNumber = getLayerNumber(y);
142 if(layerNumber != mFromLayer) {
143 if(getMouseMoveY() > 0 && y < getLayerY(layerNumber) + getLayerHeight() / 2) {
146 else if(getMouseMoveY() < 0 && y > getLayerY(layerNumber) + getLayerHeight() / 2) {
153 int TimeLineCells::getLayerY(
int layerNumber)
155 return mOffsetY + (mEditor->object()->getLayerCount() - 1 - layerNumber - mLayerOffset)*mLayerHeight;
158 void TimeLineCells::updateFrame(
int frameNumber)
160 int x = getFrameX(frameNumber);
164 void TimeLineCells::updateContent()
170 bool TimeLineCells::didDetachLayer()
const {
171 return abs(getMouseMoveY()) > mLayerDetachThreshold;
174 void TimeLineCells::drawContent()
178 if (mCache ==
nullptr)
188 mCurrentFrame = mEditor->currentFrame();
192 const Object*
object = mEditor->object();
194 Q_ASSERT(
object !=
nullptr);
196 const Layer* layer = mEditor->layers()->currentLayer();
197 if (layer ==
nullptr)
return;
205 for (
int i = 0; i <
object->getLayerCount(); i++)
207 if (i == mEditor->layers()->currentLayerIndex())
211 Layer* layeri =
object->getLayer(i);
213 if (layeri !=
nullptr)
217 case TIMELINE_CELL_TYPE::Tracks:
218 paintTrack(painter, layeri, mOffsetX,
219 getLayerY(i),
width() - mOffsetX,
220 getLayerHeight(),
false, mFrameSize);
223 case TIMELINE_CELL_TYPE::Layers:
224 paintLabel(painter, layeri, 0,
225 getLayerY(i),
width() - 1,
226 getLayerHeight(),
false, mEditor->layerVisibility());
231 if (didDetachLayer())
233 if (mType == TIMELINE_CELL_TYPE::Tracks)
235 paintTrack(painter, layer,
236 mOffsetX, getLayerY(mEditor->layers()->currentLayerIndex()) + getMouseMoveY(),
237 width() - mOffsetX, getLayerHeight(),
240 else if (mType == TIMELINE_CELL_TYPE::Layers)
242 paintLabel(painter, layer,
243 0, getLayerY(mEditor->layers()->currentLayerIndex()) + getMouseMoveY(),
244 width() - 1, getLayerHeight(),
true, mEditor->layerVisibility());
246 paintLayerGutter(painter);
251 if (mType == TIMELINE_CELL_TYPE::Tracks)
256 getLayerY(mEditor->layers()->currentLayerIndex()),
262 else if (mType == TIMELINE_CELL_TYPE::Layers)
267 getLayerY(mEditor->layers()->currentLayerIndex()),
271 mEditor->layerVisibility());
278 painter.drawRect(
QRect(0, 0,
width() - 1, mOffsetY - 1));
280 painter.drawLine(0, mOffsetY - 2,
width() - 1, mOffsetY - 2);
282 if (mType == TIMELINE_CELL_TYPE::Layers)
286 if (mEditor->layerVisibility() == LayerVisibility::CURRENTONLY)
290 else if (mEditor->layerVisibility() == LayerVisibility::RELATED)
294 painter.setBrush(color);
296 else if (mEditor->layerVisibility() == LayerVisibility::ALL)
301 painter.drawEllipse(6, 4, 9, 9);
304 else if (mType == TIMELINE_CELL_TYPE::Tracks)
309 int fps = mEditor->playback()->fps();
310 for (
int i = mFrameOffset; i < mFrameOffset + (
width() - mOffsetX) / mFrameSize; i++)
312 if (i + 1 >= mTimeLine->getRangeLower() && i < mTimeLine->getRangeUpper())
317 painter.drawRect(getFrameX(i), 1, mFrameSize + 1, 2);
323 if (i%fps == 0 || i%fps == fps / 2)
325 painter.drawLine(getFrameX(i), 1, getFrameX(i), 5);
329 painter.drawLine(getFrameX(i), 1, getFrameX(i), 3);
331 if (i == 0 || i % fps == fps - 1)
333 int incr = (i < 9) ? 4 : 0;
340 void TimeLineCells::paintTrack(
QPainter& painter,
const Layer* layer,
341 int x,
int y,
int width,
int height,
342 bool selected,
int frameSize)
const
347 if (layer->type() == Layer::BITMAP) col =
QColor(51, 155, 252);
348 if (layer->type() == Layer::VECTOR) col =
QColor(70, 205, 123);
349 if (layer->type() == Layer::SOUND) col =
QColor(255, 141, 112);
350 if (layer->type() == Layer::CAMERA) col =
QColor(253, 202, 92);
352 if (!layer->visible()) col.
setAlpha(64);
357 painter.
drawRect(x, y - 1, width, height);
359 if (!layer->visible())
return;
364 paintSelection(painter, x, y, width, height);
370 linearGrad.setColorAt(0,
QColor(255,255,255,150));
371 linearGrad.setColorAt(1,
QColor(0,0,0,0));
374 painter.
drawRect(x, y - 1, width, height);
378 paintFrames(painter, layer, col, y, height, selected, frameSize);
383 void TimeLineCells::paintFrames(
QPainter& painter,
const Layer* layer,
QColor trackCol,
int y,
int height,
bool selected,
int frameSize)
const
387 layer->foreachKeyFrame([&](
KeyFrame* key)
389 int recLeft = getFrameX(key->pos()) - frameSize + 2;
391 int recWidth = frameSize - 2;
392 int recHeight = height - 4;
394 if (key->length() > 1)
398 recWidth = frameSize * key->length() - 2;
402 if (selected && key->pos() == getCurrentFrame()) {
409 if (key->isSelected())
417 painter.
drawRect(recLeft, recTop, recWidth, recHeight);
421 void TimeLineCells::paintLabel(
QPainter& painter,
const Layer* layer,
422 int x,
int y,
int width,
int height,
423 bool selected, LayerVisibility layerVisibility)
const
436 painter.
drawRect(x, y - 1, width, height);
438 if (!layer->visible())
444 if ((layerVisibility == LayerVisibility::ALL) || selected)
448 else if (layerVisibility == LayerVisibility::CURRENTONLY)
452 else if (layerVisibility == LayerVisibility::RELATED)
471 if (layer->type() == Layer::BITMAP) painter.
drawPixmap(
QPoint(20, y + 2),
QPixmap(
":/icons/layer-bitmap.png"));
472 if (layer->type() == Layer::VECTOR) painter.
drawPixmap(
QPoint(20, y + 2),
QPixmap(
":/icons/layer-vector.png"));
474 if (layer->type() == Layer::CAMERA) painter.
drawPixmap(
QPoint(21, y + 2),
QPixmap(
":/icons/layer-camera.png"));
484 painter.
drawText(
QPoint(45, y + (2 * height) / 3), layer->name());
487 void TimeLineCells::paintSelection(
QPainter& painter,
int x,
int y,
int width,
int height)
const
490 linearGrad.setColorAt(0,
QColor(0, 0, 0, 255));
491 linearGrad.setColorAt(1,
QColor(255, 255, 255, 0));
496 painter.
drawRect(x, y, width, height - 1);
500 void TimeLineCells::paintLayerGutter(
QPainter& painter)
503 if (getMouseMoveY() > mLayerDetachThreshold)
505 painter.
drawRect(0, getLayerY(getInbetweenLayerNumber(mEndY))+mLayerHeight,
width(), 2);
509 painter.
drawRect(0, getLayerY(getInbetweenLayerNumber(mEndY)),
width(), 2);
513 void TimeLineCells::paintOnionSkin(
QPainter& painter)
515 Layer* layer = mEditor->layers()->currentLayer();
516 if (layer ==
nullptr) {
return; }
518 int frameNumber = mEditor->currentFrame();
520 int prevOnionSkinCount = mEditor->preference()->getInt(SETTING::ONION_PREV_FRAMES_NUM);
521 int nextOnionSkinCount = mEditor->preference()->getInt(SETTING::ONION_NEXT_FRAMES_NUM);
523 bool isAbsolute = (mEditor->preference()->getString(SETTING::ONION_TYPE) ==
"absolute");
525 if (mEditor->preference()->isOn(SETTING::PREV_ONION) && prevOnionSkinCount > 0)
527 int onionFrameNumber = frameNumber;
530 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber+1,
true);
532 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, isAbsolute);
533 int onionPosition = 0;
535 while (onionPosition < prevOnionSkinCount && onionFrameNumber > 0)
545 onionFrameNumber = layer->getPreviousFrameNumber(onionFrameNumber, isAbsolute);
550 if (mEditor->preference()->isOn(SETTING::NEXT_ONION) && nextOnionSkinCount > 0) {
552 int onionFrameNumber = layer->getNextFrameNumber(frameNumber, isAbsolute);
553 int onionPosition = 0;
555 while (onionPosition < nextOnionSkinCount && onionFrameNumber > 0)
565 onionFrameNumber = layer->getNextFrameNumber(onionFrameNumber, isAbsolute);
573 Object*
object = mEditor->object();
574 Layer* layer = mEditor->layers()->currentLayer();
576 Q_ASSUME(
object !=
nullptr && layer !=
nullptr);
581 bool isPlaying = mEditor->playback()->isPlaying();
582 if ((!isPlaying && !mTimeLine->scrubbing) || mCache ==
nullptr)
591 if (mType == TIMELINE_CELL_TYPE::Tracks)
595 paintOnionSkin(painter);
598 if (mPrevFrame != mEditor->currentFrame() || mEditor->playback()->isPlaying())
600 mPrevFrame = mEditor->currentFrame();
605 if (mEditor->currentFrame() > mFrameOffset)
621 int incr = (mEditor->currentFrame() < 10) ? 4 : 0;
622 painter.
drawText(
QPoint(getFrameX(mEditor->currentFrame() - 1) + incr, 15),
633 emit lengthChanged(getFrameLength());
636 void TimeLineCells::mousePressEvent(
QMouseEvent* event)
638 int frameNumber = getFrameNumber(event->
pos().
x());
639 int layerNumber = getLayerNumber(event->
pos().
y());
640 mFromLayer = mToLayer = layerNumber;
642 mStartY =
event->pos().y();
643 mStartLayerNumber = layerNumber;
644 mEndY =
event->pos().y();
646 mStartFrameNumber = frameNumber;
647 mLastFrameNumber = mStartFrameNumber;
649 mCanMoveFrame =
false;
650 mMovingFrames =
false;
652 mCanBoxSelect =
false;
653 mBoxSelecting =
false;
655 mClickSelecting =
false;
657 primaryButton =
event->button();
659 bool switchLayer = mEditor->tools()->currentTool()->switchingLayer();
660 if (!switchLayer) {
return; }
664 case TIMELINE_CELL_TYPE::Layers:
665 if (layerNumber != -1 && layerNumber < mEditor->
object()->getLayerCount())
667 if (event->
pos().
x() < 15)
669 mEditor->switchVisibilityOfLayer(layerNumber);
673 mEditor->layers()->setCurrentLayer(layerNumber);
676 if (layerNumber == -1)
678 if (event->
pos().
x() < 15)
681 mEditor->increaseLayerVisibilityIndex();
683 mEditor->decreaseLayerVisibilityIndex();
688 case TIMELINE_CELL_TYPE::Tracks:
691 mLastFrameNumber = getFrameNumber(event->
pos().
x());
695 if (frameNumber == mEditor->currentFrame() && (!mbShortScrub || (mbShortScrub && mStartY < 20)))
697 if (mEditor->playback()->isPlaying())
699 mEditor->playback()->stop();
701 mTimeLine->scrubbing =
true;
705 if ((layerNumber != -1) && layerNumber < mEditor->
object()->getLayerCount())
707 int previousLayerNumber = mEditor->layers()->currentLayerIndex();
709 if (previousLayerNumber != layerNumber) {
710 Layer *previousLayer = mEditor->object()->getLayer(previousLayerNumber);
711 previousLayer->deselectAll();
713 mEditor->layers()->setCurrentLayer(layerNumber);
716 Layer *currentLayer = mEditor->object()->getLayer(layerNumber);
722 mClickSelecting =
true;
723 mCanMoveFrame =
true;
725 currentLayer->selectAllFramesAfter(frameNumber);
728 else if (!currentLayer->isFrameSelected(frameNumber))
731 mCanBoxSelect =
true;
732 mClickSelecting =
true;
737 currentLayer->toggleFrameSelected(frameNumber,
true);
742 currentLayer->extendSelectionTo(frameNumber);
746 currentLayer->toggleFrameSelected(frameNumber,
false);
752 mCanMoveFrame =
true;
755 mTimeLine->updateContent();
761 if (mEditor->playback()->isPlaying())
763 mEditor->playback()->stop();
765 if (mEditor->playback()->getSoundScrubActive() && mLastScrubFrame != frameNumber)
767 mEditor->playback()->playScrub(frameNumber);
768 mLastScrubFrame = frameNumber;
771 mEditor->scrubTo(frameNumber);
773 mTimeLine->scrubbing =
true;
774 qDebug(
"Scrub to %d frame", frameNumber);
783 void TimeLineCells::mouseMoveEvent(
QMouseEvent* event)
785 if (mType == TIMELINE_CELL_TYPE::Layers)
787 mEndY =
event->pos().y();
788 emit mouseMovedY(mEndY - mStartY);
790 else if (mType == TIMELINE_CELL_TYPE::Tracks)
792 int frameNumber = getFrameNumber(event->
pos().
x());
796 mFrameOffset = qMin(qMax(0, mFrameLength -
width() / getFrameSize()), qMax(0, mFrameOffset + mLastFrameNumber - frameNumber));
798 emit offsetChanged(mFrameOffset);
802 if (mTimeLine->scrubbing)
804 if (mEditor->playback()->getSoundScrubActive() && mLastScrubFrame != frameNumber)
806 mEditor->playback()->playScrub(frameNumber);
807 mLastScrubFrame = frameNumber;
809 mEditor->scrubTo(frameNumber);
813 if (mStartLayerNumber != -1 && mStartLayerNumber < mEditor->
object()->getLayerCount())
815 Layer *currentLayer = mEditor->object()->getLayer(mStartLayerNumber);
818 if (frameNumber != mLastFrameNumber)
824 mMovingFrames =
true;
826 int offset = frameNumber - mLastFrameNumber;
827 currentLayer->moveSelectedFrames(offset);
828 mEditor->layers()->notifyAnimationLengthChanged();
829 mEditor->updateCurrentFrame();
831 else if (mCanBoxSelect)
834 mBoxSelecting =
true;
836 currentLayer->deselectAll();
837 currentLayer->setFrameSelected(mStartFrameNumber,
true);
838 currentLayer->extendSelectionTo(frameNumber);
840 mLastFrameNumber = frameNumber;
849 void TimeLineCells::mouseReleaseEvent(
QMouseEvent* event)
851 if (event->
button() != primaryButton)
return;
855 mTimeLine->scrubbing =
false;
856 int frameNumber = getFrameNumber(event->
pos().
x());
857 if (frameNumber < 1) frameNumber = -1;
858 int layerNumber = getLayerNumber(event->
pos().
y());
859 if (mType == TIMELINE_CELL_TYPE::Tracks && primaryButton !=
Qt::MidButton && layerNumber != -1 && layerNumber < mEditor->
object()->getLayerCount())
861 Layer *currentLayer = mEditor->object()->getLayer(layerNumber);
863 if (!mTimeLine->scrubbing && !mMovingFrames && !mClickSelecting && !mBoxSelecting)
869 currentLayer->toggleFrameSelected(frameNumber, multipleSelection);
872 if (mType == TIMELINE_CELL_TYPE::Layers && layerNumber != mStartLayerNumber && mStartLayerNumber != -1 && layerNumber != -1)
874 mToLayer = getInbetweenLayerNumber(event->
pos().
y());
875 if (mToLayer != mFromLayer && mToLayer > -1 && mToLayer < mEditor->layers()->count())
878 if (mToLayer < mFromLayer)
880 for (
int i = mFromLayer - 1; i >= mToLayer; i--)
881 mEditor->swapLayers(i, i + 1);
885 for (
int i = mFromLayer + 1; i <= mToLayer; i++)
886 mEditor->swapLayers(i, i - 1);
891 mTimeLine->updateContent();
894 void TimeLineCells::mouseDoubleClickEvent(
QMouseEvent* event)
896 int layerNumber = getLayerNumber(event->
pos().
y());
899 if (event->
pos().
y() < 20 && (mType != TIMELINE_CELL_TYPE::Layers ||
event->pos().x() >= 15))
901 mPrefs->set(SETTING::SHORT_SCRUB, !mbShortScrub);
905 Layer* layer = mEditor->object()->getLayer(layerNumber);
906 if (layer && mType == TIMELINE_CELL_TYPE::Layers && event->
pos().
x() >= 15)
908 editLayerProperties(layer);
913 void TimeLineCells::editLayerProperties(
Layer *layer)
const
915 if (layer->type() != Layer::CAMERA)
917 editLayerName(layer);
922 Q_ASSERT(cameraLayer);
923 editLayerProperties(cameraLayer);
926 void TimeLineCells::editLayerProperties(
LayerCamera *layer)
const
928 QRegExp regex(
"([\\xFFEF-\\xFFFF])+");
939 mEditor->layers()->renameLayer(layer, name);
942 settings.setValue(SETTING_FIELD_W, dialog.getWidth());
943 settings.setValue(SETTING_FIELD_H, dialog.getHeight());
944 layer->setViewRect(
QRect(-dialog.getWidth() / 2, -dialog.getHeight() / 2, dialog.getWidth(), dialog.getHeight()));
947 void TimeLineCells::editLayerName(
Layer* layer)
const
949 QRegExp regex(
"([\\xFFEF-\\xFFFF])+");
961 mEditor->layers()->renameLayer(layer, name);
964 void TimeLineCells::hScrollChange(
int x)
970 void TimeLineCells::vScrollChange(
int x)
976 void TimeLineCells::setMouseMoveY(
int x)
985 void TimeLineCells::trackScrubber()
987 if (mEditor->currentFrame() <= mFrameOffset)
990 mFrameOffset = mEditor->currentFrame() - 1;
991 emit offsetChanged(mFrameOffset);
992 mTimeLine->updateContent();
994 else if (
width() < (mEditor->currentFrame() - mFrameOffset + 1) * mFrameSize)
997 if (mEditor->playback()->isPlaying())
998 mFrameOffset = mFrameOffset + ((mEditor->currentFrame() - mFrameOffset) / 2);
1000 mFrameOffset = mEditor->currentFrame() -
width() / mFrameSize;
1001 emit offsetChanged(mFrameOffset);
1002 mTimeLine->updateContent();
void setBottomRight(const QPoint &position)
void setCompositionMode(QPainter::CompositionMode mode)
void setRenderHint(QPainter::RenderHint hint, bool on)
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
void drawRect(const QRectF &rectangle)
QString number(int n, int base)
const QBrush & brush(QPalette::ColorGroup group, QPalette::ColorRole role) const const
void setPen(const QColor &color)
void drawEllipse(const QRectF &rectangle)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
bool isEmpty() const const
void setBrush(const QBrush &brush)
void drawText(const QPointF &position, const QString &text)
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
bool isNull() const const
void setTopLeft(const QPoint &position)
QString & replace(int position, int n, QChar after)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
QObject * parent() const const