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();
133 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
136 QScrollerProperties props = scroller->scrollerProperties();
137 props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
138 props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
139 scroller->setScrollerProperties(props);
151 QAbstractItemView::setModel(model);
152 m_d->horizontalHeader->setModel(model);
154 connect(model, &QAbstractItemModel::rowsInserted,
157 connect(model, &QAbstractItemModel::rowsRemoved,
160 connect(model, &QAbstractItemModel::dataChanged,
163 connect(model, &QAbstractItemModel::headerDataChanged,
166 connect(selectionModel(), &QItemSelectionModel::selectionChanged,
167 [
this](
const QItemSelection& newSelection,
const QItemSelection& ) {
168 if (newSelection.count() == 0) {
169 activeDataChanged(QModelIndex());
171 activeDataChanged(selectionModel()->currentIndex());
181 return m_d->itemDelegate->itemRect(index);
193 if (!model())
return QModelIndex();
195 int time =
m_d->horizontalHeader->logicalIndexAt(point.x());
197 int rows = model()->rowCount();
198 for (
int row=0; row < rows; row++) {
199 QModelIndex index = model()->index(row, time);
203 QRect nodePos =
m_d->itemDelegate->itemRect(index);
205 if (nodePos.contains(point)) {
211 return QModelIndex();
216 QPainter painter(viewport());
218 QRect rect =
event->rect();
219 rect.translate(dirtyRegionOffset());
221 int firstFrame =
m_d->horizontalHeader->logicalIndexAt(rect.left());
222 int lastFrame =
m_d->horizontalHeader->logicalIndexAt(rect.right());
223 if (lastFrame == -1) lastFrame = model()->columnCount();
232 const QColor backgroundColor = qApp->palette().window().color();
233 const QColor textColor = qApp->palette().text().color();
235 const QColor zeroLineColor = qApp->palette().highlight().color();
239 const int visibleFrames =
m_d->horizontalHeader->estimateLastVisibleColumn() -
m_d->horizontalHeader->estimateFirstVisibleColumn() + 1;
240 const int firstVisibleFrame = qMax(
m_d->horizontalHeader->estimateFirstVisibleColumn() - 1, 0);
241 for (
int time = 0; time <= visibleFrames; time++) {
243 const bool activeFrame = data.isValid() && data.toBool();
246 const bool withinClipRange = data.isValid() && data.toBool();
248 const int offsetHori =
m_d->horizontalHeader ?
m_d->horizontalHeader->offset() : 0;
249 const int stepHori =
m_d->horizontalHeader->defaultSectionSize();
250 const int xPosition = stepHori * (firstVisibleFrame + time) - offsetHori;
252 QRect frameRect = QRect(xPosition, -10, stepHori, 9999);
254 const QPoint top = frameRect.topLeft() + 0.5 * (frameRect.topRight() - frameRect.topLeft());
255 const QPoint bottom = frameRect.bottomLeft() + 0.5 * (frameRect.bottomRight() - frameRect.bottomLeft());
257 QColor fadedLineColor = lineColor;
258 fadedLineColor.setAlphaF(0.33);
260 QColor finalColor = withinClipRange ? lineColor : fadedLineColor;
261 finalColor = activeFrame ? activeFrameColor : finalColor;
263 painter.setPen(finalColor);
264 painter.drawLine(top, bottom);
268 const int visibleSteps =
m_d->verticalHeader->visibleValueDifference() /
m_d->verticalHeader->step();
269 const qreal stepAmount =
m_d->verticalHeader->step();
270 for (
int step = 0; step <= visibleSteps; step++) {
271 const qreal
value =
m_d->verticalHeader->firstVisibleStep() + stepAmount * step;
272 const int CORRECTION = -1;
273 int yPosition =
m_d->verticalHeader->valueToWidget(
value);
275 QRect frameRect = QRect(-10, yPosition + CORRECTION, 9999, 1);
277 const QPoint left = frameRect.topLeft();
278 const QPoint right = frameRect.topRight();
280 painter.setPen(
value == 0 ? zeroLineColor : lineColor);
281 painter.drawLine(left, right);
287 int channels = model()->rowCount();
288 for (
int channel = 0; channel < channels; channel++) {
289 QModelIndex index0 = model()->index(channel, 0);
293 painter.setPen(QPen(color, 1));
294 painter.setRenderHint(QPainter::Antialiasing);
296 paintCurve(channel, firstFrame, lastFrame, painter);
303 int selectionOffset =
m_d->isDraggingKeyframe ? (
m_d->dragOffset.x() /
m_d->horizontalHeader->defaultSectionSize()) : 0;
306 if (!index.isValid()) {
309 if (!index.isValid())
return;
311 QPointF previousKeyPos =
m_d->itemDelegate->nodeCenter(index, selectionModel()->isSelected(index));
312 QPointF rightTangent =
m_d->itemDelegate->rightHandle(index, index == currentIndex());
314 while(index.column() <= lastFrame) {
317 int time = (
m_d->isDraggingKeyframe && selectionModel()->isSelected(index)) ? index.column() + selectionOffset : index.column();
319 if (!index.isValid())
return;
321 bool active = (index == currentIndex());
322 QPointF nextKeyPos =
m_d->itemDelegate->nodeCenter(index, selectionModel()->isSelected(index));
323 QPointF leftTangent =
m_d->itemDelegate->leftHandle(index, active);
326 painter.drawLine(previousKeyPos, QPointF(nextKeyPos.x(), previousKeyPos.y()));
328 painter.drawLine(previousKeyPos, nextKeyPos);
331 paintCurveSegment(painter, previousKeyPos, rightTangent, leftTangent, nextKeyPos, limitData);
334 previousKeyPos = nextKeyPos;
335 rightTangent =
m_d->itemDelegate->rightHandle(index, active);
340 const int steps = 32;
343 for (
int step = 0; step <= steps; step++) {
344 qreal t = 1.0 * step / steps;
347 if (limitData.isValid()) {
350 nextPos.setY(qMin(nextPos.y(),
m_d->verticalHeader->valueToWidget(limits.first)));
351 nextPos.setY(qMax(nextPos.y(),
m_d->verticalHeader->valueToWidget(limits.second)));
355 painter.drawLine(previousPos, nextPos);
358 previousPos = nextPos;
364 int channels = model()->rowCount();
365 for (
int channel = 0; channel < channels; channel++) {
366 for (
int time=firstFrame; time <= lastFrame; time++) {
367 QModelIndex index = model()->index(channel, time);
371 QStyleOptionViewItem opt;
373 if (selectionModel()->isSelected(index)) {
374 opt.state |= QStyle::State_Selected;
377 if (index == selectionModel()->currentIndex()) {
378 opt.state |= QStyle::State_HasFocus;
381 m_d->itemDelegate->paint(&painter, opt, index);
391 QModelIndex currentIndex = model()->index(channel, time);
393 if (!selectionOffset) {
394 QVariant next = currentIndex.data(role);
395 return (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
398 QModelIndex nextIndex = currentIndex;
400 QVariant next = nextIndex.data(role);
401 nextIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
402 }
while(nextIndex.isValid() && selectionModel()->isSelected(nextIndex));
405 QModelIndex draggedIndex = model()->index(channel, qMax(0, time - selectionOffset));
407 QVariant next = draggedIndex.data(role);
408 draggedIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
409 }
while(draggedIndex.isValid() && !selectionModel()->isSelected(draggedIndex));
412 if (draggedIndex.isValid() && nextIndex.isValid()) {
413 if (draggedIndex.column() + selectionOffset <= nextIndex.column()) {
418 }
else if (draggedIndex.isValid()) {
428 if (!model())
return;
433 int curveCount = model()->rowCount();
434 for (
int curveIndex = 0; curveIndex < curveCount; curveIndex++) {
435 QModelIndex index = model()->index(curveIndex, 0);
445 const int MAX_NUM_TANGENTS = 2;
446 for (
int i = 0; i < MAX_NUM_TANGENTS; i++) {
448 if (!tangent.isValid())
451 QPointF tangentPointF = tangent.toPointF();
452 if (
value + tangentPointF.y() < min) min =
value + tangentPointF.y();
453 if (
value + tangentPointF.y() > max) max =
value + tangentPointF.y();
457 if (nextTime.isValid()) index = model()->index(curveIndex, nextTime.toInt());
458 }
while (nextTime.isValid());
461 if (qIsFinite(min)) *minimum = min;
462 if (qIsFinite(max)) *maximum = max;
468 Q_UNUSED(cursorAction);
470 return QModelIndex();
475 return m_d->horizontalHeader->offset();
480 return m_d->verticalHeader->valueOffset();
490 int timeFrom =
m_d->horizontalHeader->logicalIndexAt(rect.left());
491 int timeTo =
m_d->horizontalHeader->logicalIndexAt(rect.right());
493 QItemSelection selection;
495 int rows = model()->rowCount();
496 for (
int row=0; row < rows; row++) {
497 for (
int time = timeFrom; time <= timeTo; time++) {
499 QModelIndex index = model()->index(row, time);
504 QRect itemRect =
m_d->itemDelegate->itemRect(index);
506 if (itemRect.intersects(rect)) {
507 selection.select(index, index);
513 if (!selection.contains(selectionModel()->currentIndex()) && selection.size() > 0) {
514 selectionModel()->setCurrentIndex(selection.first().topLeft(), flags);
517 selectionModel()->select(selection, flags);
518 activated(selectionModel()->currentIndex());
525 Q_FOREACH(QModelIndex index, selection.indexes()) {
526 region +=
m_d->itemDelegate->visualRect(index);
534 if (
m_d->modifiersCatcher->modifierPressed(
"pan-zoom")) {
535 if (e->button() == Qt::LeftButton) {
536 m_d->dragPanning =
true;
537 m_d->panAnchor = e->pos();
539 }
else if (e->button() == Qt::RightButton) {
540 m_d->dragZooming =
true;
541 m_d->zoomAnchor = e->pos();
543 }
else if (e->button() == Qt::LeftButton) {
544 m_d->dragStart = e->pos();
546 const int handleClickRadius = 16;
548 Q_FOREACH(QModelIndex index, selectedIndexes()) {
552 QPointF center =
m_d->itemDelegate->nodeCenter(index,
false);
553 bool hasLeftHandle =
m_d->itemDelegate->hasHandle(index, 0);
554 bool hasRightHandle =
m_d->itemDelegate->hasHandle(index, 1);
556 QPointF leftHandle = center +
m_d->itemDelegate->leftHandle(index,
false);
557 QPointF rightHandle = center +
m_d->itemDelegate->rightHandle(index,
false);
559 if (hasLeftHandle && (e->localPos() - leftHandle).manhattanLength() < handleClickRadius) {
560 m_d->isAdjustingHandle =
true;
561 m_d->adjustedHandle = 0;
562 setCurrentIndex(index);
564 }
else if (hasRightHandle && (e->localPos() - rightHandle).manhattanLength() < handleClickRadius) {
565 m_d->isAdjustingHandle =
true;
566 m_d->adjustedHandle = 1;
567 setCurrentIndex(index);
574 QModelIndex clickedIndex =
indexAt(e->pos());
576 if ((e->modifiers() & Qt::ShiftModifier) == 0 && selectionModel()->currentIndex() != clickedIndex) {
580 if (clickedIndex == selectionModel()->currentIndex() && selectionModel()->hasSelection()) {
581 m_d->deselectIntended =
true;
582 m_d->toDeselect = clickedIndex;
584 QModelIndex prevCurrent = selectionModel()->currentIndex();
585 selectionModel()->select(clickedIndex, QItemSelectionModel::Select);
586 selectionModel()->setCurrentIndex(clickedIndex, QItemSelectionModel::NoUpdate);
587 Q_EMIT currentChanged(clickedIndex, prevCurrent);
590 Q_EMIT clicked(clickedIndex);
593 QAbstractItemView::mousePressEvent(e);
600 QModelIndex clicked =
indexAt(e->pos());
603 selectionModel()->clear();
604 bool firstSelection =
true;
605 if (e->modifiers() & Qt::AltModifier) {
606 for (
int column = 0; column <= model()->columnCount(); column++) {
607 QModelIndex toSelect = model()->index(clicked.row(), column);
610 if (toSelect.isValid() && hasSpecial && curveVisible) {
611 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
612 firstSelection =
false;
616 for (
int row = 0; row <= model()->rowCount(); row++) {
617 QModelIndex toSelect = model()->index(row, clicked.column());
620 if (toSelect.isValid() && hasSpecial && curveVisible) {
621 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
622 firstSelection =
false;
627 QModelIndex oldCurrent = selectionModel()->currentIndex();
628 selectionModel()->setCurrentIndex(clicked, QItemSelectionModel::NoUpdate);
629 currentChanged(clicked, oldCurrent);
631 QAbstractItemView::mouseDoubleClickEvent(e);
637 if (
m_d->modifiersCatcher->modifierPressed(
"pan-zoom")) {
638 if (
m_d->dragPanning) {
639 const int timelineScrubAmnt =
m_d->panAnchor.x() - e->pos().x();
640 const qreal valueScrubAmnt =
m_d->verticalHeader->pixelsToValueOffset(
m_d->panAnchor.y() - e->pos().y());
644 horizontalScrollBar()->setValue(horizontalScrollBar()->
value() + timelineScrubAmnt);
646 m_d->verticalHeader->setValueOffset(
m_d->verticalHeader->valueOffset() + valueScrubAmnt);
648 m_d->panAnchor = e->pos();
649 viewport()->update();
653 if (
m_d->dragZooming) {
654 const qreal zoomScale = 50.0f;
655 const qreal updown = ((
m_d->zoomAnchor.y() - e->pos().y())) / zoomScale;
656 const qreal leftright = (
m_d->zoomAnchor.x() - e->pos().x()) / zoomScale;
661 m_d->zoomAnchor = e->pos();
662 viewport()->update();
666 }
else if (e->buttons() & Qt::LeftButton) {
668 m_d->dragOffset = e->pos() -
m_d->dragStart;
670 if (
m_d->isAdjustingHandle) {
671 m_d->itemDelegate->setHandleAdjustment(
m_d->dragOffset,
m_d->adjustedHandle);
672 viewport()->update();
674 }
else if (
m_d->isDraggingKeyframe) {
675 const bool axisSnap = (e->modifiers() & Qt::ShiftModifier);
676 m_d->itemDelegate->setSelectedItemVisualOffset(
m_d->dragOffset, axisSnap);
677 viewport()->update();
679 }
else if (selectionModel()->hasSelection()) {
680 if ((e->pos() -
m_d->dragStart).manhattanLength() > QApplication::startDragDistance()) {
681 m_d->isDraggingKeyframe =
true;
685 QAbstractItemView::mouseMoveEvent(e);
692 if (e->button() == Qt::LeftButton) {
693 m_d->dragPanning =
false;
694 m_d->dragZooming =
false;
696 if (
m_d->isDraggingKeyframe) {
698 const QPointF largestOffset = qAbs(
m_d->dragOffset.y()) > qAbs(
m_d->dragOffset.x()) ? QPointF(0.0f,
m_d->dragOffset.y()) :
699 QPointF(
m_d->dragOffset.x(), 0.0f);
702 const bool axisSnap = (e->modifiers() & Qt::ShiftModifier);
703 const QPointF offset = axisSnap ? largestOffset :
m_d->dragOffset;
704 const int timeOffset = qRound( qreal(offset.x()) /
m_d->horizontalHeader->defaultSectionSize() );
705 const qreal valueOffset =
m_d->verticalHeader->pixelsToValueOffset(offset.y());
712 Q_FOREACH(
const QModelIndex& index, indices) {
713 const bool wasCurrent = (index == selectionModel()->currentIndex());
714 selectionModel()->select(index, QItemSelectionModel::Deselect);
715 const QModelIndex newIndex =
m_d->model->index(index.row(), index.column() + timeOffset);
717 selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::SelectCurrent);
719 selectionModel()->select(newIndex, QItemSelectionModel::Select);
723 m_d->isDraggingKeyframe =
false;
724 m_d->itemDelegate->setSelectedItemVisualOffset(QPointF());
725 viewport()->update();
726 }
else if (
m_d->isAdjustingHandle) {
727 QModelIndex index = currentIndex();
733 QPointF leftHandle =
m_d->itemDelegate->leftHandle(index,
true);
734 QPointF rightHandle =
m_d->itemDelegate->rightHandle(index,
true);
736 QPointF leftTangent =
m_d->itemDelegate->unscaledTangent(leftHandle);
737 QPointF rightTangent =
m_d->itemDelegate->unscaledTangent(rightHandle);
742 if (
m_d->adjustedHandle == 0) {
743 QPointF leftHandle =
m_d->itemDelegate->leftHandle(index,
true);
746 QPointF rightHandle =
m_d->itemDelegate->rightHandle(index,
true);
751 m_d->model->endCommand();
753 m_d->isAdjustingHandle =
false;
754 m_d->itemDelegate->setHandleAdjustment(QPointF(),
m_d->adjustedHandle);
757 if (
m_d->deselectIntended){
758 selectionModel()->select(
m_d->toDeselect, QItemSelectionModel::Deselect);
763 m_d->deselectIntended =
false;
764 m_d->toDeselect = QModelIndex();
767 QAbstractItemView::mouseReleaseEvent(e);
772 scrollDirtyRegion(dx, dy);
773 viewport()->scroll(dx, dy);
774 viewport()->update();
780 return data.isValid() && data.toBool();
785 int topMargin = qMax(
m_d->horizontalHeader->minimumHeight(),
786 m_d->horizontalHeader->sizeHint().height());
788 int leftMargin =
m_d->verticalHeader->sizeHint().width();
790 setViewportMargins(leftMargin, topMargin, 0, 0);
792 QRect viewRect = viewport()->geometry();
793 m_d->horizontalHeader->setGeometry(leftMargin, 0, viewRect.width(), topMargin);
794 m_d->verticalHeader->setGeometry(0, topMargin, leftMargin, viewRect.height());
799 QAbstractItemView::updateGeometries();
804 Q_UNUSED(parentIndex);
808 viewport()->update();
814 Q_UNUSED(bottomRight);
816 viewport()->update();
820 m_d->horizontalHeader->resize(
m_d->horizontalHeader->width()-1,
m_d->horizontalHeader->height());
821 m_d->horizontalHeader->resize(
m_d->horizontalHeader->width()+1,
m_d->horizontalHeader->height());
823 if (selectionModel()->selection().count() != 0 &&
824 selectionModel()->currentIndex().isValid()) {
831 const qreal lastVisibleValue =
m_d->verticalHeader->visibleValueMax();
832 const qreal firstVisibleValue =
m_d->verticalHeader->visibleValueMin();
835 if ( value < firstVisibleValue || value > lastVisibleValue) {
838 qreal padding = (max - min) * 0.1;
839 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
840 viewport()->update();
843 selectionModel()->clear();
844 selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
849 Q_UNUSED(orientation);
852 viewport()->update();
858 const int lastColumn =
m_d->horizontalHeader->estimateLastVisibleColumn();
859 m_d->model->setLastVisibleFrame(lastColumn);
866 const int lastColumn = qMax(
m_d->horizontalHeader->estimateLastVisibleColumn(),
m_d->model->columnCount());
867 const int numberOfColumnsOnScreen = lastColumn -
m_d->horizontalHeader->estimateFirstVisibleColumn();
868 const int overallSize = lastColumn *
m_d->horizontalHeader->defaultSectionSize();
869 const int pageStep = overallSize * (qreal(numberOfColumnsOnScreen) / lastColumn);
870 horizontalScrollBar()->setRange(0, overallSize + pageStep);
871 horizontalScrollBar()->setPageStep(pageStep);
878 Q_FOREACH(QModelIndex index, selectedIndexes()) {
881 m_d->model->endCommand();
887 Q_FOREACH(QModelIndex index, selectedIndexes()) {
890 m_d->model->endCommand();
896 Q_FOREACH(QModelIndex index, selectedIndexes()) {
899 m_d->model->endCommand();
905 Q_FOREACH(QModelIndex index, selectedIndexes()) {
906 QVector2D leftVisualTangent(
m_d->itemDelegate->leftHandle(index,
false));
907 QVector2D rightVisualTangent(
m_d->itemDelegate->rightHandle(index,
false));
909 if (leftVisualTangent.lengthSquared() > 0 && rightVisualTangent.lengthSquared() > 0) {
910 float leftAngle = qAtan2(-leftVisualTangent.y(), -leftVisualTangent.x());
911 float rightAngle = qAtan2(rightVisualTangent.y(), rightVisualTangent.x());
912 float angle = (leftAngle + rightAngle) / 2;
913 QVector2D unit(qCos(angle), qSin(angle));
915 leftVisualTangent = -unit * QVector2D(leftVisualTangent).length();
916 rightVisualTangent = unit * QVector2D(rightVisualTangent).length();
918 QPointF leftTangent =
m_d->itemDelegate->unscaledTangent(leftVisualTangent.toPointF());
919 QPointF rightTangent =
m_d->itemDelegate->unscaledTangent(rightVisualTangent.toPointF());
927 m_d->model->endCommand();
933 Q_FOREACH(QModelIndex index, selectedIndexes()) {
936 m_d->model->endCommand();
941 QModelIndex active = currentIndex();
942 int channel = active.isValid() ? active.row() : 0;
944 int time =
m_d->model->currentTime();
945 QModelIndex index =
m_d->model->index(channel, time);
953 m_d->model->removeFrames(selectedIndexes());
959 if (!model())
return;
964 const qreal padding = (min != max) ? (max - min) * 0.1 : 10.0f;
965 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
966 viewport()->update();
971 if (!model())
return;
973 const int channels = model()->rowCount();
978 for (
int channel = 0; channel < channels; channel++) {
979 QModelIndex index =
m_d->model->index(channel, 0);
982 if (!variant.isValid())
986 min = qMin(limits.first, min);
987 max = qMax(limits.second, max);
996 const qreal padding = (max - min) * 0.1;
997 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
998 viewport()->update();
1003 if (orientation == Qt::Horizontal) {
1004 m_d->horizontalHeader->setZoom(
m_d->horizontalHeader->zoom() + zoomDelta);
1007 const qreal currentZoomLevel =
m_d->verticalHeader->scale();
1008 m_d->verticalHeader->setScale(currentZoomLevel + zoomDelta /
m_d->verticalHeader->step());
1010 viewport()->update();
float value(const T *src, size_t ch)
QPair< qreal, qreal > ChannelLimitsMetatype
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