10#include <QApplication>
59 : QAbstractItemView(parent)
68 m_d->modifiersCatcher->addModifier(
"pan-zoom", Qt::Key_Space);
70 setSelectionMode(QAbstractItemView::ExtendedSelection);
73 setHorizontalScrollBar(horiZoomableBar);
74 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
75 setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
77 connect(horiZoomableBar, &KisZoomableScrollBar::valueChanged, [
this](qreal
value){
78 m_d->horizontalHeader->setPixelOffset(
value);
86 m_d->horizontalHeader->setPixelOffset(
m_d->horizontalHeader->offset() + overscroll);
93 qreal currentZoomLevel =
m_d->horizontalHeader->
zoom();
94 m_d->horizontalHeader->setZoom(currentZoomLevel + zoomDelta);
102 setVerticalScrollBar(vertZoomableBar);
103 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
104 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
105 vertZoomableBar->setWheelOverscrollSensitivity( 0.04f );
108 const qreal currentZoomLevel =
m_d->verticalHeader->scale();
109 m_d->verticalHeader->setScale(currentZoomLevel + zoomDelta /
m_d->verticalHeader->step());
113 qreal currentOffset =
m_d->verticalHeader->valueOffset();
114 m_d->verticalHeader->setValueOffset(currentOffset - overscroll *
m_d->verticalHeader->step() * 0.25);
118 viewport()->update();
122 viewport()->update();
127 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
130 QScrollerProperties props = scroller->scrollerProperties();
131 props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
132 props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
133 scroller->setScrollerProperties(props);
144 QAbstractItemView::setModel(model);
145 m_d->horizontalHeader->setModel(model);
147 connect(model, &QAbstractItemModel::rowsInserted,
150 connect(model, &QAbstractItemModel::rowsRemoved,
153 connect(model, &QAbstractItemModel::dataChanged,
156 connect(model, &QAbstractItemModel::headerDataChanged,
159 connect(selectionModel(), &QItemSelectionModel::selectionChanged,
160 [
this](
const QItemSelection& newSelection,
const QItemSelection& ) {
161 if (newSelection.count() == 0) {
162 activeDataChanged(QModelIndex());
164 activeDataChanged(selectionModel()->currentIndex());
174 return m_d->itemDelegate->itemRect(index);
186 if (!model())
return QModelIndex();
188 int time =
m_d->horizontalHeader->logicalIndexAt(point.x());
190 int rows = model()->rowCount();
191 for (
int row=0; row < rows; row++) {
192 QModelIndex index = model()->index(row, time);
196 QRect nodePos =
m_d->itemDelegate->itemRect(index);
198 if (nodePos.contains(point)) {
204 return QModelIndex();
209 QPainter painter(viewport());
211 QRect
rect =
event->rect();
212 rect.translate(dirtyRegionOffset());
214 int firstFrame =
m_d->horizontalHeader->logicalIndexAt(
rect.left());
215 int lastFrame =
m_d->horizontalHeader->logicalIndexAt(
rect.right());
216 if (lastFrame == -1) lastFrame = model()->columnCount();
225 const QColor backgroundColor = qApp->palette().window().color();
226 const QColor textColor = qApp->palette().text().color();
228 const QColor zeroLineColor = qApp->palette().highlight().color();
232 const int visibleFrames =
m_d->horizontalHeader->estimateLastVisibleColumn() -
m_d->horizontalHeader->estimateFirstVisibleColumn() + 1;
233 const int firstVisibleFrame = qMax(
m_d->horizontalHeader->estimateFirstVisibleColumn() - 1, 0);
234 for (
int time = 0; time <= visibleFrames; time++) {
236 const bool activeFrame = data.isValid() && data.toBool();
239 const bool withinClipRange = data.isValid() && data.toBool();
241 const int offsetHori =
m_d->horizontalHeader ?
m_d->horizontalHeader->offset() : 0;
242 const int stepHori =
m_d->horizontalHeader->defaultSectionSize();
243 const int xPosition = stepHori * (firstVisibleFrame + time) - offsetHori;
245 QRect frameRect = QRect(xPosition, -10, stepHori, 9999);
247 const QPoint top = frameRect.topLeft() + 0.5 * (frameRect.topRight() - frameRect.topLeft());
248 const QPoint bottom = frameRect.bottomLeft() + 0.5 * (frameRect.bottomRight() - frameRect.bottomLeft());
250 QColor fadedLineColor = lineColor;
251 fadedLineColor.setAlphaF(0.33);
253 QColor finalColor = withinClipRange ? lineColor : fadedLineColor;
254 finalColor = activeFrame ? activeFrameColor : finalColor;
256 painter.setPen(finalColor);
257 painter.drawLine(top, bottom);
261 const int visibleSteps =
m_d->verticalHeader->visibleValueDifference() /
m_d->verticalHeader->step();
262 const qreal stepAmount =
m_d->verticalHeader->step();
263 for (
int step = 0; step <= visibleSteps; step++) {
264 const qreal
value =
m_d->verticalHeader->firstVisibleStep() + stepAmount * step;
265 const int CORRECTION = -1;
266 int yPosition =
m_d->verticalHeader->valueToWidget(
value);
268 QRect frameRect = QRect(-10, yPosition + CORRECTION, 9999, 1);
270 const QPoint left = frameRect.topLeft();
271 const QPoint right = frameRect.topRight();
273 painter.setPen(
value == 0 ? zeroLineColor : lineColor);
274 painter.drawLine(left, right);
280 int channels = model()->rowCount();
281 for (
int channel = 0; channel < channels; channel++) {
282 QModelIndex index0 = model()->index(channel, 0);
286 painter.setPen(QPen(color, 1));
287 painter.setRenderHint(QPainter::Antialiasing);
289 paintCurve(channel, firstFrame, lastFrame, painter);
296 int selectionOffset =
m_d->isDraggingKeyframe ? (
m_d->dragOffset.x() /
m_d->horizontalHeader->defaultSectionSize()) : 0;
299 if (!index.isValid()) {
302 if (!index.isValid())
return;
304 QPointF previousKeyPos =
m_d->itemDelegate->nodeCenter(index, selectionModel()->isSelected(index));
305 QPointF rightTangent =
m_d->itemDelegate->rightHandle(index, index == currentIndex());
307 while(index.column() <= lastFrame) {
310 int time = (
m_d->isDraggingKeyframe && selectionModel()->isSelected(index)) ? index.column() + selectionOffset : index.column();
312 if (!index.isValid())
return;
314 bool active = (index == currentIndex());
315 QPointF nextKeyPos =
m_d->itemDelegate->nodeCenter(index, selectionModel()->isSelected(index));
316 QPointF leftTangent =
m_d->itemDelegate->leftHandle(index, active);
319 painter.drawLine(previousKeyPos, QPointF(nextKeyPos.x(), previousKeyPos.y()));
321 painter.drawLine(previousKeyPos, nextKeyPos);
324 paintCurveSegment(painter, previousKeyPos, rightTangent, leftTangent, nextKeyPos, limitData);
327 previousKeyPos = nextKeyPos;
328 rightTangent =
m_d->itemDelegate->rightHandle(index, active);
333 const int steps = 32;
336 for (
int step = 0; step <= steps; step++) {
337 qreal t = 1.0 * step / steps;
340 if (limitData.isValid()) {
343 nextPos.setY(qMin(nextPos.y(),
m_d->verticalHeader->valueToWidget(limits.first)));
344 nextPos.setY(qMax(nextPos.y(),
m_d->verticalHeader->valueToWidget(limits.second)));
348 painter.drawLine(previousPos, nextPos);
351 previousPos = nextPos;
357 int channels = model()->rowCount();
358 for (
int channel = 0; channel < channels; channel++) {
359 for (
int time=firstFrame; time <= lastFrame; time++) {
360 QModelIndex index = model()->index(channel, time);
364 QStyleOptionViewItem opt;
366 if (selectionModel()->isSelected(index)) {
367 opt.state |= QStyle::State_Selected;
370 if (index == selectionModel()->currentIndex()) {
371 opt.state |= QStyle::State_HasFocus;
374 m_d->itemDelegate->paint(&painter, opt, index);
384 QModelIndex currentIndex = model()->index(channel, time);
386 if (!selectionOffset) {
387 QVariant next = currentIndex.data(role);
388 return (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
391 QModelIndex nextIndex = currentIndex;
393 QVariant next = nextIndex.data(role);
394 nextIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
395 }
while(nextIndex.isValid() && selectionModel()->isSelected(nextIndex));
398 QModelIndex draggedIndex = model()->index(channel, qMax(0, time - selectionOffset));
400 QVariant next = draggedIndex.data(role);
401 draggedIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
402 }
while(draggedIndex.isValid() && !selectionModel()->isSelected(draggedIndex));
405 if (draggedIndex.isValid() && nextIndex.isValid()) {
406 if (draggedIndex.column() + selectionOffset <= nextIndex.column()) {
411 }
else if (draggedIndex.isValid()) {
421 if (!model())
return;
426 int curveCount = model()->rowCount();
427 for (
int curveIndex = 0; curveIndex < curveCount; curveIndex++) {
428 QModelIndex index = model()->index(curveIndex, 0);
438 const int MAX_NUM_TANGENTS = 2;
439 for (
int i = 0; i < MAX_NUM_TANGENTS; i++) {
441 if (!tangent.isValid())
444 QPointF tangentPointF = tangent.toPointF();
445 if (
value + tangentPointF.y() < min) min =
value + tangentPointF.y();
446 if (
value + tangentPointF.y() > max) max =
value + tangentPointF.y();
450 if (nextTime.isValid()) index = model()->index(curveIndex, nextTime.toInt());
451 }
while (nextTime.isValid());
454 if (qIsFinite(min)) *minimum = min;
455 if (qIsFinite(max)) *maximum = max;
461 Q_UNUSED(cursorAction);
463 return QModelIndex();
468 return m_d->horizontalHeader->offset();
473 return m_d->verticalHeader->valueOffset();
483 int timeFrom =
m_d->horizontalHeader->logicalIndexAt(
rect.left());
484 int timeTo =
m_d->horizontalHeader->logicalIndexAt(
rect.right());
486 QItemSelection selection;
488 int rows = model()->rowCount();
489 for (
int row=0; row < rows; row++) {
490 for (
int time = timeFrom; time <= timeTo; time++) {
492 QModelIndex index = model()->index(row, time);
497 QRect itemRect =
m_d->itemDelegate->itemRect(index);
499 if (itemRect.intersects(
rect)) {
500 selection.select(index, index);
506 if (!selection.contains(selectionModel()->currentIndex()) && selection.size() > 0) {
507 selectionModel()->setCurrentIndex(selection.first().topLeft(), flags);
510 selectionModel()->select(selection, flags);
511 activated(selectionModel()->currentIndex());
518 Q_FOREACH(QModelIndex index, selection.indexes()) {
519 region +=
m_d->itemDelegate->visualRect(index);
527 if (
m_d->modifiersCatcher->modifierPressed(
"pan-zoom")) {
528 if (e->button() == Qt::LeftButton) {
529 m_d->dragPanning =
true;
530 m_d->panAnchor = e->pos();
532 }
else if (e->button() == Qt::RightButton) {
533 m_d->dragZooming =
true;
534 m_d->zoomAnchor = e->pos();
536 }
else if (e->button() == Qt::LeftButton) {
537 m_d->dragStart = e->pos();
539 const int handleClickRadius = 16;
541 Q_FOREACH(QModelIndex index, selectedIndexes()) {
545 QPointF center =
m_d->itemDelegate->nodeCenter(index,
false);
546 bool hasLeftHandle =
m_d->itemDelegate->hasHandle(index, 0);
547 bool hasRightHandle =
m_d->itemDelegate->hasHandle(index, 1);
549 QPointF leftHandle = center +
m_d->itemDelegate->leftHandle(index,
false);
550 QPointF rightHandle = center +
m_d->itemDelegate->rightHandle(index,
false);
552 if (hasLeftHandle && (e->localPos() - leftHandle).manhattanLength() < handleClickRadius) {
553 m_d->isAdjustingHandle =
true;
554 m_d->adjustedHandle = 0;
555 setCurrentIndex(index);
557 }
else if (hasRightHandle && (e->localPos() - rightHandle).manhattanLength() < handleClickRadius) {
558 m_d->isAdjustingHandle =
true;
559 m_d->adjustedHandle = 1;
560 setCurrentIndex(index);
567 QModelIndex clickedIndex =
indexAt(e->pos());
569 if ((e->modifiers() & Qt::ShiftModifier) == 0 && selectionModel()->currentIndex() != clickedIndex) {
573 if (clickedIndex == selectionModel()->currentIndex() && selectionModel()->hasSelection()) {
574 m_d->deselectIntended =
true;
575 m_d->toDeselect = clickedIndex;
577 QModelIndex prevCurrent = selectionModel()->currentIndex();
578 selectionModel()->select(clickedIndex, QItemSelectionModel::Select);
579 selectionModel()->setCurrentIndex(clickedIndex, QItemSelectionModel::NoUpdate);
580 Q_EMIT currentChanged(clickedIndex, prevCurrent);
583 Q_EMIT clicked(clickedIndex);
586 QAbstractItemView::mousePressEvent(e);
593 QModelIndex clicked =
indexAt(e->pos());
596 selectionModel()->clear();
597 bool firstSelection =
true;
598 if (e->modifiers() & Qt::AltModifier) {
599 for (
int column = 0; column <= model()->columnCount(); column++) {
600 QModelIndex toSelect = model()->index(clicked.row(), column);
603 if (toSelect.isValid() && hasSpecial && curveVisible) {
604 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
605 firstSelection =
false;
609 for (
int row = 0; row <= model()->rowCount(); row++) {
610 QModelIndex toSelect = model()->index(row, clicked.column());
613 if (toSelect.isValid() && hasSpecial && curveVisible) {
614 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
615 firstSelection =
false;
620 QModelIndex oldCurrent = selectionModel()->currentIndex();
621 selectionModel()->setCurrentIndex(clicked, QItemSelectionModel::NoUpdate);
622 currentChanged(clicked, oldCurrent);
624 QAbstractItemView::mouseDoubleClickEvent(e);
630 if (
m_d->modifiersCatcher->modifierPressed(
"pan-zoom")) {
631 if (
m_d->dragPanning) {
632 const int timelineScrubAmnt =
m_d->panAnchor.x() - e->pos().x();
633 const qreal valueScrubAmnt =
m_d->verticalHeader->pixelsToValueOffset(
m_d->panAnchor.y() - e->pos().y());
637 horizontalScrollBar()->setValue(horizontalScrollBar()->
value() + timelineScrubAmnt);
639 m_d->verticalHeader->setValueOffset(
m_d->verticalHeader->valueOffset() + valueScrubAmnt);
641 m_d->panAnchor = e->pos();
642 viewport()->update();
646 if (
m_d->dragZooming) {
647 const qreal zoomScale = 50.0f;
648 const qreal updown = ((
m_d->zoomAnchor.y() - e->pos().y())) / zoomScale;
649 const qreal leftright = (
m_d->zoomAnchor.x() - e->pos().x()) / zoomScale;
654 m_d->zoomAnchor = e->pos();
655 viewport()->update();
659 }
else if (e->buttons() & Qt::LeftButton) {
661 m_d->dragOffset = e->pos() -
m_d->dragStart;
663 if (
m_d->isAdjustingHandle) {
664 m_d->itemDelegate->setHandleAdjustment(
m_d->dragOffset,
m_d->adjustedHandle);
665 viewport()->update();
667 }
else if (
m_d->isDraggingKeyframe) {
668 const bool axisSnap = (e->modifiers() & Qt::ShiftModifier);
669 m_d->itemDelegate->setSelectedItemVisualOffset(
m_d->dragOffset, axisSnap);
670 viewport()->update();
672 }
else if (selectionModel()->hasSelection()) {
673 if ((e->pos() -
m_d->dragStart).manhattanLength() > QApplication::startDragDistance()) {
674 m_d->isDraggingKeyframe =
true;
678 QAbstractItemView::mouseMoveEvent(e);
685 if (e->button() == Qt::LeftButton) {
686 m_d->dragPanning =
false;
687 m_d->dragZooming =
false;
689 if (
m_d->isDraggingKeyframe) {
691 const QPointF largestOffset = qAbs(
m_d->dragOffset.y()) > qAbs(
m_d->dragOffset.x()) ? QPointF(0.0f,
m_d->dragOffset.y()) :
692 QPointF(
m_d->dragOffset.x(), 0.0f);
695 const bool axisSnap = (e->modifiers() & Qt::ShiftModifier);
696 const QPointF offset = axisSnap ? largestOffset :
m_d->dragOffset;
697 const int timeOffset = qRound( qreal(offset.x()) /
m_d->horizontalHeader->defaultSectionSize() );
698 const qreal valueOffset =
m_d->verticalHeader->pixelsToValueOffset(offset.y());
705 Q_FOREACH(
const QModelIndex& index, indices) {
706 const bool wasCurrent = (index == selectionModel()->currentIndex());
707 selectionModel()->select(index, QItemSelectionModel::Deselect);
708 const QModelIndex newIndex =
m_d->model->index(index.row(), index.column() + timeOffset);
710 selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::SelectCurrent);
712 selectionModel()->select(newIndex, QItemSelectionModel::Select);
716 m_d->isDraggingKeyframe =
false;
717 m_d->itemDelegate->setSelectedItemVisualOffset(QPointF());
718 viewport()->update();
719 }
else if (
m_d->isAdjustingHandle) {
720 QModelIndex index = currentIndex();
726 QPointF leftHandle =
m_d->itemDelegate->leftHandle(index,
true);
727 QPointF rightHandle =
m_d->itemDelegate->rightHandle(index,
true);
729 QPointF leftTangent =
m_d->itemDelegate->unscaledTangent(leftHandle);
730 QPointF rightTangent =
m_d->itemDelegate->unscaledTangent(rightHandle);
735 if (
m_d->adjustedHandle == 0) {
736 QPointF leftHandle =
m_d->itemDelegate->leftHandle(index,
true);
739 QPointF rightHandle =
m_d->itemDelegate->rightHandle(index,
true);
744 m_d->model->endCommand();
746 m_d->isAdjustingHandle =
false;
747 m_d->itemDelegate->setHandleAdjustment(QPointF(),
m_d->adjustedHandle);
750 if (
m_d->deselectIntended){
751 selectionModel()->select(
m_d->toDeselect, QItemSelectionModel::Deselect);
756 m_d->deselectIntended =
false;
757 m_d->toDeselect = QModelIndex();
760 QAbstractItemView::mouseReleaseEvent(e);
765 scrollDirtyRegion(dx, dy);
766 viewport()->scroll(dx, dy);
767 viewport()->update();
773 return data.isValid() && data.toBool();
778 int topMargin = qMax(
m_d->horizontalHeader->minimumHeight(),
779 m_d->horizontalHeader->sizeHint().height());
781 int leftMargin =
m_d->verticalHeader->sizeHint().width();
783 setViewportMargins(leftMargin, topMargin, 0, 0);
785 QRect viewRect = viewport()->geometry();
786 m_d->horizontalHeader->setGeometry(leftMargin, 0, viewRect.width(), topMargin);
787 m_d->verticalHeader->setGeometry(0, topMargin, leftMargin, viewRect.height());
792 QAbstractItemView::updateGeometries();
797 Q_UNUSED(parentIndex);
801 viewport()->update();
807 Q_UNUSED(bottomRight);
809 viewport()->update();
813 m_d->horizontalHeader->resize(
m_d->horizontalHeader->width()-1,
m_d->horizontalHeader->height());
814 m_d->horizontalHeader->resize(
m_d->horizontalHeader->width()+1,
m_d->horizontalHeader->height());
816 if (selectionModel()->selection().count() != 0 &&
817 selectionModel()->currentIndex().isValid()) {
824 const qreal lastVisibleValue =
m_d->verticalHeader->visibleValueMax();
825 const qreal firstVisibleValue =
m_d->verticalHeader->visibleValueMin();
828 if ( value < firstVisibleValue || value > lastVisibleValue) {
831 qreal padding = (max - min) * 0.1;
832 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
833 viewport()->update();
836 selectionModel()->clear();
837 selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
842 Q_UNUSED(orientation);
845 viewport()->update();
851 const int lastColumn =
m_d->horizontalHeader->estimateLastVisibleColumn();
852 m_d->model->setLastVisibleFrame(lastColumn);
859 const int lastColumn = qMax(
m_d->horizontalHeader->estimateLastVisibleColumn(),
m_d->model->columnCount());
860 const int numberOfColumnsOnScreen = lastColumn -
m_d->horizontalHeader->estimateFirstVisibleColumn();
861 const int overallSize = lastColumn *
m_d->horizontalHeader->defaultSectionSize();
862 const int pageStep = overallSize * (qreal(numberOfColumnsOnScreen) / lastColumn);
863 horizontalScrollBar()->setRange(0, overallSize + pageStep);
864 horizontalScrollBar()->setPageStep(pageStep);
871 Q_FOREACH(QModelIndex index, selectedIndexes()) {
874 m_d->model->endCommand();
880 Q_FOREACH(QModelIndex index, selectedIndexes()) {
883 m_d->model->endCommand();
889 Q_FOREACH(QModelIndex index, selectedIndexes()) {
892 m_d->model->endCommand();
898 Q_FOREACH(QModelIndex index, selectedIndexes()) {
899 QVector2D leftVisualTangent(
m_d->itemDelegate->leftHandle(index,
false));
900 QVector2D rightVisualTangent(
m_d->itemDelegate->rightHandle(index,
false));
902 if (leftVisualTangent.lengthSquared() > 0 && rightVisualTangent.lengthSquared() > 0) {
903 float leftAngle = qAtan2(-leftVisualTangent.y(), -leftVisualTangent.x());
904 float rightAngle = qAtan2(rightVisualTangent.y(), rightVisualTangent.x());
905 float angle = (leftAngle + rightAngle) / 2;
906 QVector2D unit(qCos(angle), qSin(angle));
908 leftVisualTangent = -unit * QVector2D(leftVisualTangent).length();
909 rightVisualTangent = unit * QVector2D(rightVisualTangent).length();
911 QPointF leftTangent =
m_d->itemDelegate->unscaledTangent(leftVisualTangent.toPointF());
912 QPointF rightTangent =
m_d->itemDelegate->unscaledTangent(rightVisualTangent.toPointF());
920 m_d->model->endCommand();
926 Q_FOREACH(QModelIndex index, selectedIndexes()) {
929 m_d->model->endCommand();
934 QModelIndex active = currentIndex();
935 int channel = active.isValid() ? active.row() : 0;
937 int time =
m_d->model->currentTime();
938 QModelIndex index =
m_d->model->index(channel, time);
946 m_d->model->removeFrames(selectedIndexes());
952 if (!model())
return;
957 const qreal padding = (min != max) ? (max - min) * 0.1 : 10.0f;
958 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
959 viewport()->update();
964 if (!model())
return;
966 const int channels = model()->rowCount();
971 for (
int channel = 0; channel < channels; channel++) {
972 QModelIndex index =
m_d->model->index(channel, 0);
975 if (!variant.isValid())
979 min = qMin(limits.first, min);
980 max = qMax(limits.second, max);
989 const qreal padding = (max - min) * 0.1;
990 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
991 viewport()->update();
996 if (orientation == Qt::Horizontal) {
997 m_d->horizontalHeader->setZoom(
m_d->horizontalHeader->zoom() + zoomDelta);
1000 const qreal currentZoomLevel =
m_d->verticalHeader->scale();
1001 m_d->verticalHeader->setScale(currentZoomLevel + zoomDelta /
m_d->verticalHeader->step());
1003 viewport()->update();
float value(const T *src, size_t ch)
QPair< qreal, qreal > ChannelLimitsMetatype
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
bool adjustKeyframes(const QModelIndexList &indexes, int timeOffset, qreal valueOffset)
void dataAdded(const QModelIndex &index)
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
void paintCurves(QPainter &painter, int firstFrame, int lastFrame)
void paintEvent(QPaintEvent *event) override
void mouseMoveEvent(QMouseEvent *) override
void slotUpdateHorizontalScrollbarSize()
void scrollTo(const QModelIndex &index, ScrollHint hint) override
QModelIndex findNextKeyframeIndex(int channel, int time, int selectionOffset, bool backward)
void mouseReleaseEvent(QMouseEvent *) override
void updateGeometries() override
bool indexHasKey(const QModelIndex &index)
void setModel(QAbstractItemModel *model) override
void slotRowsChanged(const QModelIndex &parentIndex, int first, int last)
void slotUpdateInfiniteFramesCount()
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override
void paintCurve(int channel, int firstFrame, int lastFrame, QPainter &painter)
int verticalOffset() const override
void activeDataChanged(const QModelIndex &index)
bool isIndexHidden(const QModelIndex &index) const override
QModelIndex indexAt(const QPoint &point) const override
void changeZoom(Qt::Orientation orientation, qreal zoomDelta)
const QScopedPointer< Private > m_d
KisAnimCurvesView(QWidget *parent)
void slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
~KisAnimCurvesView() override
void paintCurveSegment(QPainter &painter, QPointF pos1, QPointF rightTangent, QPointF leftTangent, QPointF pos2, QVariant limitData)
void paintKeyframes(QPainter &painter, int firstFrame, int lastFrame)
void slotScrollerStateChanged(QScroller::State state)
void paintGrid(QPainter &painter)
QRect visualRect(const QModelIndex &index) const override
void scrollContentsBy(int dx, int dy) override
void mousePressEvent(QMouseEvent *) override
void slotDataAdded(const QModelIndex &index)
void slotHeaderDataChanged(Qt::Orientation orientation, int first, int last)
QRegion visualRegionForSelection(const QItemSelection &selection) const override
void findExtremes(qreal *minimum, qreal *maximum)
int horizontalOffset() const override
void mouseDoubleClickEvent(QMouseEvent *) override
QBrush headerActive() const
static KisAnimTimelineColors * instance()
The KisCustomModifiersCatcher class is a special utility class that tracks custom modifiers pressed....
static QPointF interpolate(QPointF point1, QPointF rightTangent, QPointF leftTangent, QPointF point2, qreal t)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
KUndo2MagicString kundo2_i18n(const char *text)
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)
qreal verticalZoomStillPointOriginalOffset
KisCustomModifiersCatcher * modifiersCatcher
KisAnimTimelineTimeHeader * horizontalHeader
int horizontalZoomStillPointOriginalOffset
KisAnimCurvesKeyDelegate * itemDelegate
KisAnimCurvesModel * model
KisAnimCurvesValuesHeader * verticalHeader
int horizontalZoomStillPointIndex
qreal verticalZoomStillPoint