Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAnimCurvesView Class Reference

#include <KisAnimCurvesView.h>

+ Inheritance diagram for KisAnimCurvesView:

Classes

struct  Private
 

Public Slots

void applyBezierMode ()
 
void applyConstantMode ()
 
void applyLinearMode ()
 
void applySharpMode ()
 
void applySmoothMode ()
 
void changeZoom (Qt::Orientation orientation, qreal zoomDelta)
 
void createKeyframe ()
 
void removeKeyframes ()
 
void slotScrollerStateChanged (QScroller::State state)
 
void zoomToFitChannel ()
 
void zoomToFitCurve ()
 

Signals

void activeDataChanged (const QModelIndex &index)
 

Public Member Functions

QModelIndex indexAt (const QPoint &point) const override
 
bool indexHasKey (const QModelIndex &index)
 
 KisAnimCurvesView (QWidget *parent)
 
void scrollTo (const QModelIndex &index, ScrollHint hint) override
 
void setModel (QAbstractItemModel *model) override
 
QRect visualRect (const QModelIndex &index) const override
 
 ~KisAnimCurvesView () override
 

Protected Slots

void updateGeometries () override
 

Protected Member Functions

int horizontalOffset () const override
 
bool isIndexHidden (const QModelIndex &index) const override
 
void mouseDoubleClickEvent (QMouseEvent *) override
 
void mouseMoveEvent (QMouseEvent *) override
 
void mousePressEvent (QMouseEvent *) override
 
void mouseReleaseEvent (QMouseEvent *) override
 
QModelIndex moveCursor (CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override
 
void paintEvent (QPaintEvent *event) override
 
void scrollContentsBy (int dx, int dy) override
 
void setSelection (const QRect &rect, QItemSelectionModel::SelectionFlags flags) override
 
int verticalOffset () const override
 
QRegion visualRegionForSelection (const QItemSelection &selection) const override
 

Private Slots

void slotDataAdded (const QModelIndex &index)
 
void slotDataChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight)
 
void slotHeaderDataChanged (Qt::Orientation orientation, int first, int last)
 
void slotRowsChanged (const QModelIndex &parentIndex, int first, int last)
 
void slotUpdateHorizontalScrollbarSize ()
 
void slotUpdateInfiniteFramesCount ()
 

Private Member Functions

void findExtremes (qreal *minimum, qreal *maximum)
 
QModelIndex findNextKeyframeIndex (int channel, int time, int selectionOffset, bool backward)
 
void paintCurve (int channel, int firstFrame, int lastFrame, QPainter &painter)
 
void paintCurves (QPainter &painter, int firstFrame, int lastFrame)
 
void paintCurveSegment (QPainter &painter, QPointF pos1, QPointF rightTangent, QPointF leftTangent, QPointF pos2, QVariant limitData)
 
void paintGrid (QPainter &painter)
 
void paintKeyframes (QPainter &painter, int firstFrame, int lastFrame)
 

Private Attributes

const QScopedPointer< Private > m_d
 

Detailed Description

Definition at line 17 of file KisAnimCurvesView.h.

Constructor & Destructor Documentation

◆ KisAnimCurvesView()

KisAnimCurvesView::KisAnimCurvesView ( QWidget * parent)

Definition at line 58 of file KisAnimCurvesView.cpp.

59 : QAbstractItemView(parent)
60 , m_d(new Private())
61{
62 m_d->horizontalHeader = new KisAnimTimelineTimeHeader(this);
63
64 m_d->verticalHeader = new KisAnimCurvesValuesHeader(this);
65 m_d->itemDelegate = new KisAnimCurvesKeyDelegate(m_d->horizontalHeader, m_d->verticalHeader, this);
66
67 m_d->modifiersCatcher = new KisCustomModifiersCatcher(this);
68 m_d->modifiersCatcher->addModifier("pan-zoom", Qt::Key_Space);
69
70 setSelectionMode(QAbstractItemView::ExtendedSelection);
71
72 KisZoomableScrollBar* horiZoomableBar = new KisZoomableScrollBar(this);
73 setHorizontalScrollBar(horiZoomableBar);
74 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
75 setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
76
77 connect(horiZoomableBar, &KisZoomableScrollBar::valueChanged, [this](qreal value){
78 m_d->horizontalHeader->setPixelOffset(value);
80 viewport()->update();
81 });
82
83 connect(horiZoomableBar, &KisZoomableScrollBar::sliderReleased, this, &KisAnimCurvesView::slotUpdateHorizontalScrollbarSize);
84
85 connect(horiZoomableBar, &KisZoomableScrollBar::overscroll, [this](qreal overscroll){
86 m_d->horizontalHeader->setPixelOffset(m_d->horizontalHeader->offset() + overscroll);
89 viewport()->update();
90 });
91
92 connect(horiZoomableBar, &KisZoomableScrollBar::zoom, [this](qreal zoomDelta){
93 qreal currentZoomLevel = m_d->horizontalHeader->zoom();
94 m_d->horizontalHeader->setZoom(currentZoomLevel + zoomDelta);
97 viewport()->update();
98 });
99
100
101 KisZoomableScrollBar* vertZoomableBar = new KisZoomableScrollBar(this);
102 setVerticalScrollBar(vertZoomableBar);
103 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
104 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
105 vertZoomableBar->setWheelOverscrollSensitivity( 0.04f );
106
107 connect(vertZoomableBar, &KisZoomableScrollBar::zoom, [this](qreal zoomDelta){
108 const qreal currentZoomLevel = m_d->verticalHeader->scale();
109 m_d->verticalHeader->setScale(currentZoomLevel + zoomDelta / m_d->verticalHeader->step());
110 });
111
112 connect(vertZoomableBar, &KisZoomableScrollBar::overscroll, [this](qreal overscroll){
113 qreal currentOffset = m_d->verticalHeader->valueOffset();
114 m_d->verticalHeader->setValueOffset(currentOffset - overscroll * m_d->verticalHeader->step() * 0.25);
115 });
116
117 connect(m_d->verticalHeader, &KisAnimCurvesValuesHeader::scaleChanged, [this](qreal){
118 viewport()->update();
119 });
120
121 connect(m_d->verticalHeader, &KisAnimCurvesValuesHeader::valueOffsetChanged, [this](qreal){
122 viewport()->update();
123 });
124
125 // Kinetic scrolling via left-click completely breaks everything, it somehow
126 // ends up reporting left clicks as right clicks and makes the whole curves
127 // view behave erratically with regards to when it wants to scroll and when
128 // you're dragging pints. So we don't enable kinetic scrolling in that case
129 // and require the use of the scrollbar instead, like on the timeline.
130 if (KisKineticScroller::getConfiguredGestureType() != QScroller::LeftMouseButtonGesture) {
131 QScroller *scroller = KisKineticScroller::createPreconfiguredScroller(this);
132 if (scroller){
133 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
134 this, SLOT(slotScrollerStateChanged(QScroller::State)));
135
136 QScrollerProperties props = scroller->scrollerProperties();
137 props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
138 props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
139 scroller->setScrollerProperties(props);
140 }
141 }
142}
float value(const T *src, size_t ch)
void valueOffsetChanged(qreal offset)
void scaleChanged(qreal scale)
const QScopedPointer< Private > m_d
void slotScrollerStateChanged(QScroller::State state)
The KisCustomModifiersCatcher class is a special utility class that tracks custom modifiers pressed....
void overscroll(qreal delta)
void zoom(qreal delta)
KRITAWIDGETUTILS_EXPORT QScroller::ScrollerGestureType getConfiguredGestureType()
KRITAWIDGETUTILS_EXPORT QScroller * createPreconfiguredScroller(QAbstractScrollArea *target)

References KisKineticScroller::createPreconfiguredScroller(), KisKineticScroller::getConfiguredGestureType(), m_d, KisZoomableScrollBar::overscroll(), KisAnimCurvesValuesHeader::scaleChanged(), slotScrollerStateChanged(), slotUpdateHorizontalScrollbarSize(), slotUpdateInfiniteFramesCount(), value(), KisAnimCurvesValuesHeader::valueOffsetChanged(), and KisZoomableScrollBar::zoom().

◆ ~KisAnimCurvesView()

KisAnimCurvesView::~KisAnimCurvesView ( )
override

Definition at line 144 of file KisAnimCurvesView.cpp.

145{}

Member Function Documentation

◆ activeDataChanged

void KisAnimCurvesView::activeDataChanged ( const QModelIndex & index)
signal

◆ applyBezierMode

void KisAnimCurvesView::applyBezierMode ( )
slot

Definition at line 893 of file KisAnimCurvesView.cpp.

894{
895 m_d->model->beginCommand(kundo2_i18n("Set interpolation mode"));
896 Q_FOREACH(QModelIndex index, selectedIndexes()) {
898 }
899 m_d->model->endCommand();
900}
KUndo2MagicString kundo2_i18n(const char *text)

References KisScalarKeyframe::Bezier, KisAnimCurvesModel::InterpolationModeRole, kundo2_i18n(), and m_d.

◆ applyConstantMode

void KisAnimCurvesView::applyConstantMode ( )
slot

Definition at line 875 of file KisAnimCurvesView.cpp.

876{
877 m_d->model->beginCommand(kundo2_i18n("Set interpolation mode"));
878 Q_FOREACH(QModelIndex index, selectedIndexes()) {
880 }
881 m_d->model->endCommand();
882}

References KisScalarKeyframe::Constant, KisAnimCurvesModel::InterpolationModeRole, kundo2_i18n(), and m_d.

◆ applyLinearMode

void KisAnimCurvesView::applyLinearMode ( )
slot

Definition at line 884 of file KisAnimCurvesView.cpp.

885{
886 m_d->model->beginCommand(kundo2_i18n("Set interpolation mode"));
887 Q_FOREACH(QModelIndex index, selectedIndexes()) {
889 }
890 m_d->model->endCommand();
891}

References KisAnimCurvesModel::InterpolationModeRole, kundo2_i18n(), KisScalarKeyframe::Linear, and m_d.

◆ applySharpMode

void KisAnimCurvesView::applySharpMode ( )
slot

Definition at line 930 of file KisAnimCurvesView.cpp.

931{
932 m_d->model->beginCommand(kundo2_i18n("Set interpolation mode"));
933 Q_FOREACH(QModelIndex index, selectedIndexes()) {
935 }
936 m_d->model->endCommand();
937}

References kundo2_i18n(), m_d, KisScalarKeyframe::Sharp, and KisAnimCurvesModel::TangentsModeRole.

◆ applySmoothMode

void KisAnimCurvesView::applySmoothMode ( )
slot

Definition at line 902 of file KisAnimCurvesView.cpp.

903{
904 m_d->model->beginCommand(kundo2_i18n("Set interpolation mode"));
905 Q_FOREACH(QModelIndex index, selectedIndexes()) {
906 QVector2D leftVisualTangent(m_d->itemDelegate->leftHandle(index, false));
907 QVector2D rightVisualTangent(m_d->itemDelegate->rightHandle(index, false));
908
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));
914
915 leftVisualTangent = -unit * QVector2D(leftVisualTangent).length();
916 rightVisualTangent = unit * QVector2D(rightVisualTangent).length();
917
918 QPointF leftTangent = m_d->itemDelegate->unscaledTangent(leftVisualTangent.toPointF());
919 QPointF rightTangent = m_d->itemDelegate->unscaledTangent(rightVisualTangent.toPointF());
920
921 model()->setData(index, leftTangent, KisAnimCurvesModel::LeftTangentRole);
922 model()->setData(index, rightTangent, KisAnimCurvesModel::RightTangentRole);
923 }
924
926 }
927 m_d->model->endCommand();
928}

References kundo2_i18n(), KisAnimCurvesModel::LeftTangentRole, m_d, KisAnimCurvesModel::RightTangentRole, KisScalarKeyframe::Smooth, and KisAnimCurvesModel::TangentsModeRole.

◆ changeZoom

void KisAnimCurvesView::changeZoom ( Qt::Orientation orientation,
qreal zoomDelta )
slot

Definition at line 1001 of file KisAnimCurvesView.cpp.

1002{
1003 if (orientation == Qt::Horizontal) {
1004 m_d->horizontalHeader->setZoom( m_d->horizontalHeader->zoom() + zoomDelta);
1006 } else {
1007 const qreal currentZoomLevel = m_d->verticalHeader->scale();
1008 m_d->verticalHeader->setScale(currentZoomLevel + zoomDelta / m_d->verticalHeader->step());
1009 }
1010 viewport()->update();
1011}

References m_d, and slotUpdateInfiniteFramesCount().

◆ createKeyframe

void KisAnimCurvesView::createKeyframe ( )
slot

Definition at line 939 of file KisAnimCurvesView.cpp.

940{
941 QModelIndex active = currentIndex();
942 int channel = active.isValid() ? active.row() : 0;
943
944 int time = m_d->model->currentTime();
945 QModelIndex index = m_d->model->index(channel, time);
946
947 qreal value = index.data(KisAnimCurvesModel::ScalarValueRole).toReal();
948 m_d->model->setData(index, value, KisAnimCurvesModel::ScalarValueRole);
949}

References m_d, KisAnimCurvesModel::ScalarValueRole, and value().

◆ findExtremes()

void KisAnimCurvesView::findExtremes ( qreal * minimum,
qreal * maximum )
private

Definition at line 426 of file KisAnimCurvesView.cpp.

427{
428 if (!model()) return;
429
430 qreal min = qInf();
431 qreal max = -qInf();
432
433 int curveCount = model()->rowCount();
434 for (int curveIndex = 0; curveIndex < curveCount; curveIndex++) {
435 QModelIndex index = model()->index(curveIndex, 0);
436 if (isIndexHidden(index)) continue;
437
438 QVariant nextTime;
439 do {
440 qreal value = index.data(KisAnimCurvesModel::ScalarValueRole).toReal();
441
442 if (value < min) min = value;
443 if (value > max) max = value;
444
445 const int MAX_NUM_TANGENTS = 2;
446 for (int i = 0; i < MAX_NUM_TANGENTS; i++) {
447 QVariant tangent = index.data(KisAnimCurvesModel::LeftTangentRole + i);
448 if (!tangent.isValid())
449 continue;
450
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();
454 }
455
456 nextTime = index.data(KisAnimCurvesModel::NextKeyframeTime);
457 if (nextTime.isValid()) index = model()->index(curveIndex, nextTime.toInt());
458 } while (nextTime.isValid());
459 }
460
461 if (qIsFinite(min)) *minimum = min;
462 if (qIsFinite(max)) *maximum = max;
463}
bool isIndexHidden(const QModelIndex &index) const override
T min(T a, T b, T c)
constexpr std::enable_if< sizeof...(values)==0, size_t >::type max()

References isIndexHidden(), KisAnimCurvesModel::LeftTangentRole, KisAnimCurvesModel::NextKeyframeTime, KisAnimCurvesModel::ScalarValueRole, and value().

◆ findNextKeyframeIndex()

QModelIndex KisAnimCurvesView::findNextKeyframeIndex ( int channel,
int time,
int selectionOffset,
bool backward )
private

Definition at line 387 of file KisAnimCurvesView.cpp.

388{
391 QModelIndex currentIndex = model()->index(channel, time);
392
393 if (!selectionOffset) {
394 QVariant next = currentIndex.data(role);
395 return (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
396 } else {
397 // Find the next unselected index
398 QModelIndex nextIndex = currentIndex;
399 do {
400 QVariant next = nextIndex.data(role);
401 nextIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
402 } while(nextIndex.isValid() && selectionModel()->isSelected(nextIndex));
403
404 // Find the next selected index, accounting for D&D offset
405 QModelIndex draggedIndex = model()->index(channel, qMax(0, time - selectionOffset));
406 do {
407 QVariant next = draggedIndex.data(role);
408 draggedIndex = (next.isValid()) ? model()->index(channel, next.toInt()) : QModelIndex();
409 } while(draggedIndex.isValid() && !selectionModel()->isSelected(draggedIndex));
410
411 // Choose the earlier of the two
412 if (draggedIndex.isValid() && nextIndex.isValid()) {
413 if (draggedIndex.column() + selectionOffset <= nextIndex.column()) {
414 return draggedIndex;
415 } else {
416 return nextIndex;
417 }
418 } else if (draggedIndex.isValid()) {
419 return draggedIndex;
420 } else {
421 return nextIndex;
422 }
423 }
424}
QAction * next(const QObject *recvr, const char *slot, QObject *parent)

References KisAnimCurvesModel::NextKeyframeTime, and KisAnimCurvesModel::PreviousKeyframeTime.

◆ horizontalOffset()

int KisAnimCurvesView::horizontalOffset ( ) const
overrideprotected

Definition at line 473 of file KisAnimCurvesView.cpp.

474{
475 return m_d->horizontalHeader->offset();
476}

References m_d.

◆ indexAt()

QModelIndex KisAnimCurvesView::indexAt ( const QPoint & point) const
override

Definition at line 191 of file KisAnimCurvesView.cpp.

192{
193 if (!model()) return QModelIndex();
194
195 int time = m_d->horizontalHeader->logicalIndexAt(point.x());
196
197 int rows = model()->rowCount();
198 for (int row=0; row < rows; row++) {
199 QModelIndex index = model()->index(row, time);
200
201 if (index.data(KisTimeBasedItemModel::SpecialKeyframeExists).toBool()
202 && index.data(KisAnimCurvesModel::CurveVisibleRole).toBool()) {
203 QRect nodePos = m_d->itemDelegate->itemRect(index);
204
205 if (nodePos.contains(point)) {
206 return index;
207 }
208 }
209 }
210
211 return QModelIndex();
212}

References KisAnimCurvesModel::CurveVisibleRole, m_d, and KisTimeBasedItemModel::SpecialKeyframeExists.

◆ indexHasKey()

bool KisAnimCurvesView::indexHasKey ( const QModelIndex & index)

Definition at line 777 of file KisAnimCurvesView.cpp.

778{
779 const QVariant data = m_d->model->data(index, KisAnimCurvesModel::SpecialKeyframeExists);
780 return data.isValid() && data.toBool();
781}

References m_d, and KisTimeBasedItemModel::SpecialKeyframeExists.

◆ isIndexHidden()

bool KisAnimCurvesView::isIndexHidden ( const QModelIndex & index) const
overrideprotected

Definition at line 483 of file KisAnimCurvesView.cpp.

484{
485 return !index.data(KisAnimCurvesModel::CurveVisibleRole).toBool();
486}

References KisAnimCurvesModel::CurveVisibleRole.

◆ mouseDoubleClickEvent()

void KisAnimCurvesView::mouseDoubleClickEvent ( QMouseEvent * e)
overrideprotected

Definition at line 598 of file KisAnimCurvesView.cpp.

599{
600 QModelIndex clicked = indexAt(e->pos());
601
602 if(clicked.isValid() && indexHasKey(clicked)) {
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);
608 const bool hasSpecial = toSelect.data(KisTimeBasedItemModel::SpecialKeyframeExists).toBool();
609 const bool curveVisible = toSelect.data(KisAnimCurvesModel::CurveVisibleRole).toBool();
610 if (toSelect.isValid() && hasSpecial && curveVisible) {
611 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
612 firstSelection = false;
613 }
614 }
615 } else {
616 for (int row = 0; row <= model()->rowCount(); row++) {
617 QModelIndex toSelect = model()->index(row, clicked.column());
618 const bool hasSpecial = toSelect.data(KisTimeBasedItemModel::SpecialKeyframeExists).toBool();
619 const bool curveVisible = toSelect.data(KisAnimCurvesModel::CurveVisibleRole).toBool();
620 if (toSelect.isValid() && hasSpecial && curveVisible) {
621 selectionModel()->select(toSelect, firstSelection ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Select);
622 firstSelection = false;
623 }
624 }
625 }
626
627 QModelIndex oldCurrent = selectionModel()->currentIndex();
628 selectionModel()->setCurrentIndex(clicked, QItemSelectionModel::NoUpdate);
629 currentChanged(clicked, oldCurrent);
630 } else {
631 QAbstractItemView::mouseDoubleClickEvent(e);
632 }
633}
bool indexHasKey(const QModelIndex &index)
QModelIndex indexAt(const QPoint &point) const override

References KisAnimCurvesModel::CurveVisibleRole, indexAt(), indexHasKey(), and KisTimeBasedItemModel::SpecialKeyframeExists.

◆ mouseMoveEvent()

void KisAnimCurvesView::mouseMoveEvent ( QMouseEvent * e)
overrideprotected

Definition at line 635 of file KisAnimCurvesView.cpp.

636{
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());
641
644 horizontalScrollBar()->setValue(horizontalScrollBar()->value() + timelineScrubAmnt);
645
646 m_d->verticalHeader->setValueOffset(m_d->verticalHeader->valueOffset() + valueScrubAmnt);
647
648 m_d->panAnchor = e->pos();
649 viewport()->update();
650 return;
651 }
652
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;
657
658 changeZoom(Qt::Vertical, updown);
659 changeZoom(Qt::Horizontal, leftright * -0.5);
660
661 m_d->zoomAnchor = e->pos();
662 viewport()->update();
663 return;
664 }
665
666 } else if (e->buttons() & Qt::LeftButton) {
667
668 m_d->dragOffset = e->pos() - m_d->dragStart;
669
670 if (m_d->isAdjustingHandle) {
671 m_d->itemDelegate->setHandleAdjustment(m_d->dragOffset, m_d->adjustedHandle);
672 viewport()->update();
673 return;
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();
678 return;
679 } else if (selectionModel()->hasSelection()) {
680 if ((e->pos() - m_d->dragStart).manhattanLength() > QApplication::startDragDistance()) {
681 m_d->isDraggingKeyframe = true;
682 }
683 }
684 } else {
685 QAbstractItemView::mouseMoveEvent(e);
686 }
687}
void changeZoom(Qt::Orientation orientation, qreal zoomDelta)

References changeZoom(), m_d, slotUpdateHorizontalScrollbarSize(), slotUpdateInfiniteFramesCount(), and value().

◆ mousePressEvent()

void KisAnimCurvesView::mousePressEvent ( QMouseEvent * e)
overrideprotected

Definition at line 532 of file KisAnimCurvesView.cpp.

533{
534 if (m_d->modifiersCatcher->modifierPressed("pan-zoom")) {
535 if (e->button() == Qt::LeftButton) { // PAN
536 m_d->dragPanning = true;
537 m_d->panAnchor = e->pos();
538
539 } else if (e->button() == Qt::RightButton) { // ZOOM
540 m_d->dragZooming = true;
541 m_d->zoomAnchor = e->pos();
542 }
543 } else if (e->button() == Qt::LeftButton) { // SELECT
544 m_d->dragStart = e->pos();
545
546 const int handleClickRadius = 16;
547
548 Q_FOREACH(QModelIndex index, selectedIndexes()) {
549
550 if (isIndexHidden(index)) continue;
551
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);
555
556 QPointF leftHandle = center + m_d->itemDelegate->leftHandle(index, false);
557 QPointF rightHandle = center + m_d->itemDelegate->rightHandle(index, false);
558
559 if (hasLeftHandle && (e->localPos() - leftHandle).manhattanLength() < handleClickRadius) {
560 m_d->isAdjustingHandle = true;
561 m_d->adjustedHandle = 0;
562 setCurrentIndex(index);
563 continue;
564 } else if (hasRightHandle && (e->localPos() - rightHandle).manhattanLength() < handleClickRadius) {
565 m_d->isAdjustingHandle = true;
566 m_d->adjustedHandle = 1;
567 setCurrentIndex(index);
568 continue;
569 }
570 }
571
572 }
573
574 QModelIndex clickedIndex = indexAt(e->pos());
575 if(indexHasKey(clickedIndex)) {
576 if ((e->modifiers() & Qt::ShiftModifier) == 0 && selectionModel()->currentIndex() != clickedIndex) {
577 clearSelection();
578 }
579
580 if (clickedIndex == selectionModel()->currentIndex() && selectionModel()->hasSelection()) {
581 m_d->deselectIntended = true;
582 m_d->toDeselect = clickedIndex;
583 } else {
584 QModelIndex prevCurrent = selectionModel()->currentIndex();
585 selectionModel()->select(clickedIndex, QItemSelectionModel::Select);
586 selectionModel()->setCurrentIndex(clickedIndex, QItemSelectionModel::NoUpdate);
587 Q_EMIT currentChanged(clickedIndex, prevCurrent);
588 }
589
590 Q_EMIT clicked(clickedIndex);
591 Q_EMIT activeDataChanged(selectionModel()->currentIndex());
592 } else {
593 QAbstractItemView::mousePressEvent(e);
594 }
595}
void activeDataChanged(const QModelIndex &index)

References activeDataChanged(), indexAt(), indexHasKey(), isIndexHidden(), and m_d.

◆ mouseReleaseEvent()

void KisAnimCurvesView::mouseReleaseEvent ( QMouseEvent * e)
overrideprotected

Definition at line 689 of file KisAnimCurvesView.cpp.

690{
691
692 if (e->button() == Qt::LeftButton) {
693 m_d->dragPanning = false;
694 m_d->dragZooming = false;
695
696 if (m_d->isDraggingKeyframe) {
697 const QModelIndexList indices = selectedIndexes();
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);
700
701 //Only use the largest offset when axis snap is enabled on mouse button release..
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());
706
707 KisAnimCurvesModel *curvesModel = dynamic_cast<KisAnimCurvesModel*>(model());
709 curvesModel->adjustKeyframes(indices, timeOffset, valueOffset);
710
711 //Adjust selection to match new keyframe adjustment.
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);
716 if (wasCurrent) {
717 selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::SelectCurrent);
718 } else {
719 selectionModel()->select(newIndex, QItemSelectionModel::Select);
720 }
721 }
722
723 m_d->isDraggingKeyframe = false;
724 m_d->itemDelegate->setSelectedItemVisualOffset(QPointF());
725 viewport()->update();
726 } else if (m_d->isAdjustingHandle) {
727 QModelIndex index = currentIndex();
728 int mode = index.data(KisAnimCurvesModel::TangentsModeRole).toInt();
729
730 m_d->model->beginCommand(kundo2_i18n("Adjust tangent"));
731
732 if (mode == KisScalarKeyframe::Smooth) {
733 QPointF leftHandle = m_d->itemDelegate->leftHandle(index, true);
734 QPointF rightHandle = m_d->itemDelegate->rightHandle(index, true);
735
736 QPointF leftTangent = m_d->itemDelegate->unscaledTangent(leftHandle);
737 QPointF rightTangent = m_d->itemDelegate->unscaledTangent(rightHandle);
738
739 model()->setData(index, leftTangent, KisAnimCurvesModel::LeftTangentRole);
740 model()->setData(index, rightTangent, KisAnimCurvesModel::RightTangentRole);
741 } else {
742 if (m_d->adjustedHandle == 0) {
743 QPointF leftHandle = m_d->itemDelegate->leftHandle(index, true);
744 model()->setData(index, m_d->itemDelegate->unscaledTangent(leftHandle), KisAnimCurvesModel::LeftTangentRole);
745 } else {
746 QPointF rightHandle = m_d->itemDelegate->rightHandle(index, true);
747 model()->setData(index, m_d->itemDelegate->unscaledTangent(rightHandle), KisAnimCurvesModel::RightTangentRole);
748 }
749 }
750
751 m_d->model->endCommand();
752
753 m_d->isAdjustingHandle = false;
754 m_d->itemDelegate->setHandleAdjustment(QPointF(), m_d->adjustedHandle);
755 } else {
756
757 if (m_d->deselectIntended){
758 selectionModel()->select(m_d->toDeselect, QItemSelectionModel::Deselect);
759 }
760
761 }
762
763 m_d->deselectIntended = false;
764 m_d->toDeselect = QModelIndex();
765 }
766
767 QAbstractItemView::mouseReleaseEvent(e);
768}
bool adjustKeyframes(const QModelIndexList &indexes, int timeOffset, qreal valueOffset)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KisAnimCurvesModel::adjustKeyframes(), KIS_SAFE_ASSERT_RECOVER_RETURN, kundo2_i18n(), KisAnimCurvesModel::LeftTangentRole, m_d, KisAnimCurvesModel::RightTangentRole, KisScalarKeyframe::Smooth, and KisAnimCurvesModel::TangentsModeRole.

◆ moveCursor()

QModelIndex KisAnimCurvesView::moveCursor ( CursorAction cursorAction,
Qt::KeyboardModifiers modifiers )
overrideprotected

Definition at line 465 of file KisAnimCurvesView.cpp.

466{
467 // TODO
468 Q_UNUSED(cursorAction);
469 Q_UNUSED(modifiers);
470 return QModelIndex();
471}

◆ paintCurve()

void KisAnimCurvesView::paintCurve ( int channel,
int firstFrame,
int lastFrame,
QPainter & painter )
private

Definition at line 301 of file KisAnimCurvesView.cpp.

302{
303 int selectionOffset = m_d->isDraggingKeyframe ? (m_d->dragOffset.x() / m_d->horizontalHeader->defaultSectionSize()) : 0;
304
305 QModelIndex index = findNextKeyframeIndex(channel, firstFrame+1, selectionOffset, true);
306 if (!index.isValid()) {
307 index = findNextKeyframeIndex(channel, firstFrame, selectionOffset, false);
308 }
309 if (!index.isValid()) return;
310
311 QPointF previousKeyPos = m_d->itemDelegate->nodeCenter(index, selectionModel()->isSelected(index));
312 QPointF rightTangent = m_d->itemDelegate->rightHandle(index, index == currentIndex());
313
314 while(index.column() <= lastFrame) {
315 int interpolationMode = index.data(KisAnimCurvesModel::InterpolationModeRole).toInt();
316
317 int time = (m_d->isDraggingKeyframe && selectionModel()->isSelected(index)) ? index.column() + selectionOffset : index.column();
318 index = findNextKeyframeIndex(channel, time, selectionOffset, false);
319 if (!index.isValid()) return;
320
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);
324
325 if (interpolationMode == KisScalarKeyframe::Constant) {
326 painter.drawLine(previousKeyPos, QPointF(nextKeyPos.x(), previousKeyPos.y()));
327 } else if (interpolationMode == KisScalarKeyframe::Linear) {
328 painter.drawLine(previousKeyPos, nextKeyPos);
329 } else {
330 QVariant limitData = m_d->model->data(m_d->model->index(channel, index.column()), KisAnimCurvesModel::ChannelLimits);
331 paintCurveSegment(painter, previousKeyPos, rightTangent, leftTangent, nextKeyPos, limitData);
332 }
333
334 previousKeyPos = nextKeyPos;
335 rightTangent = m_d->itemDelegate->rightHandle(index, active);
336 }
337}
QModelIndex findNextKeyframeIndex(int channel, int time, int selectionOffset, bool backward)
void paintCurveSegment(QPainter &painter, QPointF pos1, QPointF rightTangent, QPointF leftTangent, QPointF pos2, QVariant limitData)

References KisAnimCurvesModel::ChannelLimits, KisScalarKeyframe::Constant, findNextKeyframeIndex(), KisAnimCurvesModel::InterpolationModeRole, KisScalarKeyframe::Linear, m_d, and paintCurveSegment().

◆ paintCurves()

void KisAnimCurvesView::paintCurves ( QPainter & painter,
int firstFrame,
int lastFrame )
private

Definition at line 285 of file KisAnimCurvesView.cpp.

286{
287 int channels = model()->rowCount();
288 for (int channel = 0; channel < channels; channel++) {
289 QModelIndex index0 = model()->index(channel, 0);
290
291 if (!isIndexHidden(index0)) {
292 QColor color = index0.data(KisAnimCurvesModel::CurveColorRole).value<QColor>();
293 painter.setPen(QPen(color, 1));
294 painter.setRenderHint(QPainter::Antialiasing);
295
296 paintCurve(channel, firstFrame, lastFrame, painter);
297 }
298 }
299}
void paintCurve(int channel, int firstFrame, int lastFrame, QPainter &painter)

References KisAnimCurvesModel::CurveColorRole, isIndexHidden(), and paintCurve().

◆ paintCurveSegment()

void KisAnimCurvesView::paintCurveSegment ( QPainter & painter,
QPointF pos1,
QPointF rightTangent,
QPointF leftTangent,
QPointF pos2,
QVariant limitData )
private

Definition at line 339 of file KisAnimCurvesView.cpp.

339 {
340 const int steps = 32;
341 QPointF previousPos;
342
343 for (int step = 0; step <= steps; step++) {
344 qreal t = 1.0 * step / steps;
345
346 QPointF nextPos = KisScalarKeyframeChannel::interpolate(pos1, rightTangent, leftTangent, pos2, t);
347 if (limitData.isValid()) {
348 ChannelLimitsMetatype limits = limitData.value<ChannelLimitsMetatype>();
349
350 nextPos.setY(qMin(nextPos.y(), m_d->verticalHeader->valueToWidget(limits.first)));
351 nextPos.setY(qMax(nextPos.y(), m_d->verticalHeader->valueToWidget(limits.second)));
352 }
353
354 if (step > 0) {
355 painter.drawLine(previousPos, nextPos);
356 }
357
358 previousPos = nextPos;
359 }
360}
QPair< qreal, qreal > ChannelLimitsMetatype
static QPointF interpolate(QPointF point1, QPointF rightTangent, QPointF leftTangent, QPointF point2, qreal t)

References KisScalarKeyframeChannel::interpolate(), and m_d.

◆ paintEvent()

void KisAnimCurvesView::paintEvent ( QPaintEvent * event)
overrideprotected

Definition at line 214 of file KisAnimCurvesView.cpp.

215{
216 QPainter painter(viewport());
217
218 QRect rect = event->rect();
219 rect.translate(dirtyRegionOffset());
220
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();
224
225 paintGrid(painter);
226 paintCurves(painter, firstFrame, lastFrame);
227 paintKeyframes(painter, firstFrame, lastFrame);
228}
void paintCurves(QPainter &painter, int firstFrame, int lastFrame)
void paintKeyframes(QPainter &painter, int firstFrame, int lastFrame)
void paintGrid(QPainter &painter)

References m_d, paintCurves(), paintGrid(), and paintKeyframes().

◆ paintGrid()

void KisAnimCurvesView::paintGrid ( QPainter & painter)
private

Definition at line 230 of file KisAnimCurvesView.cpp.

231{
232 const QColor backgroundColor = qApp->palette().window().color();
233 const QColor textColor = qApp->palette().text().color();
234 const QColor lineColor = KisPaintingTweaks::blendColors(textColor, backgroundColor, 0.1);
235 const QColor zeroLineColor = qApp->palette().highlight().color();
236 const QColor activeFrameColor = KisAnimTimelineColors::instance()->headerActive().color();
237
238 // Draw vertical lines..
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++) {
242 QVariant data = m_d->model->headerData(firstVisibleFrame + time, Qt::Horizontal, KisTimeBasedItemModel::ActiveFrameRole);
243 const bool activeFrame = data.isValid() && data.toBool();
244
245 data = m_d->model->headerData(firstVisibleFrame + time, Qt::Horizontal, KisTimeBasedItemModel::WithinClipRange);
246 const bool withinClipRange = data.isValid() && data.toBool();
247
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;
251
252 QRect frameRect = QRect(xPosition, -10, stepHori, 9999);
253
254 const QPoint top = frameRect.topLeft() + 0.5 * (frameRect.topRight() - frameRect.topLeft());
255 const QPoint bottom = frameRect.bottomLeft() + 0.5 * (frameRect.bottomRight() - frameRect.bottomLeft());
256
257 QColor fadedLineColor = lineColor;
258 fadedLineColor.setAlphaF(0.33);
259
260 QColor finalColor = withinClipRange ? lineColor : fadedLineColor;
261 finalColor = activeFrame ? activeFrameColor : finalColor;
262
263 painter.setPen(finalColor);
264 painter.drawLine(top, bottom);
265 }
266
267 // Draw horizontal lines..
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);
274
275 QRect frameRect = QRect(-10, yPosition + CORRECTION, 9999, 1);
276
277 const QPoint left = frameRect.topLeft();
278 const QPoint right = frameRect.topRight();
279
280 painter.setPen(value == 0 ? zeroLineColor : lineColor);
281 painter.drawLine(left, right);
282 }
283}
static KisAnimTimelineColors * instance()
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)

References KisTimeBasedItemModel::ActiveFrameRole, KisPaintingTweaks::blendColors(), KisAnimTimelineColors::headerActive(), KisAnimTimelineColors::instance(), m_d, value(), and KisTimeBasedItemModel::WithinClipRange.

◆ paintKeyframes()

void KisAnimCurvesView::paintKeyframes ( QPainter & painter,
int firstFrame,
int lastFrame )
private

Definition at line 362 of file KisAnimCurvesView.cpp.

363{
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);
368 bool keyframeExists = model()->data(index, KisAnimCurvesModel::SpecialKeyframeExists).toReal();
369
370 if (keyframeExists && !isIndexHidden(index)) {
371 QStyleOptionViewItem opt;
372
373 if (selectionModel()->isSelected(index)) {
374 opt.state |= QStyle::State_Selected;
375 }
376
377 if (index == selectionModel()->currentIndex()) {
378 opt.state |= QStyle::State_HasFocus;
379 }
380
381 m_d->itemDelegate->paint(&painter, opt, index);
382 }
383 }
384 }
385}

References isIndexHidden(), m_d, and KisTimeBasedItemModel::SpecialKeyframeExists.

◆ removeKeyframes

void KisAnimCurvesView::removeKeyframes ( )
slot

Definition at line 951 of file KisAnimCurvesView.cpp.

952{
953 m_d->model->removeFrames(selectedIndexes());
954}

References m_d.

◆ scrollContentsBy()

void KisAnimCurvesView::scrollContentsBy ( int dx,
int dy )
overrideprotected

Definition at line 770 of file KisAnimCurvesView.cpp.

771{
772 scrollDirtyRegion(dx, dy);
773 viewport()->scroll(dx, dy);
774 viewport()->update();
775}

◆ scrollTo()

void KisAnimCurvesView::scrollTo ( const QModelIndex & index,
ScrollHint hint )
override

Definition at line 184 of file KisAnimCurvesView.cpp.

185{
186 // TODO
187 Q_UNUSED(index);
188 Q_UNUSED(hint);
189}

◆ setModel()

void KisAnimCurvesView::setModel ( QAbstractItemModel * model)
override

Definition at line 147 of file KisAnimCurvesView.cpp.

148{
149 m_d->model = dynamic_cast<KisAnimCurvesModel*>(model);
150
151 QAbstractItemView::setModel(model);
152 m_d->horizontalHeader->setModel(model);
153
154 connect(model, &QAbstractItemModel::rowsInserted,
156
157 connect(model, &QAbstractItemModel::rowsRemoved,
159
160 connect(model, &QAbstractItemModel::dataChanged,
162
163 connect(model, &QAbstractItemModel::headerDataChanged,
165
166 connect(selectionModel(), &QItemSelectionModel::selectionChanged,
167 [this](const QItemSelection& newSelection, const QItemSelection& /*oldSelection*/) {
168 if (newSelection.count() == 0) {
169 activeDataChanged(QModelIndex());
170 } else {
171 activeDataChanged(selectionModel()->currentIndex());
172 }
173 });
174
175 connect(m_d->model, &KisAnimCurvesModel::dataAdded,
177}
void dataAdded(const QModelIndex &index)
void slotRowsChanged(const QModelIndex &parentIndex, int first, int last)
void slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
void slotDataAdded(const QModelIndex &index)
void slotHeaderDataChanged(Qt::Orientation orientation, int first, int last)

References KisAnimCurvesModel::dataAdded(), m_d, slotDataAdded(), slotDataChanged(), slotHeaderDataChanged(), and slotRowsChanged().

◆ setSelection()

void KisAnimCurvesView::setSelection ( const QRect & rect,
QItemSelectionModel::SelectionFlags flags )
overrideprotected

Definition at line 488 of file KisAnimCurvesView.cpp.

489{
490 int timeFrom = m_d->horizontalHeader->logicalIndexAt(rect.left());
491 int timeTo = m_d->horizontalHeader->logicalIndexAt(rect.right());
492
493 QItemSelection selection;
494
495 int rows = model()->rowCount();
496 for (int row=0; row < rows; row++) {
497 for (int time = timeFrom; time <= timeTo; time++) {
498
499 QModelIndex index = model()->index(row, time);
500
501 if (isIndexHidden(index)) continue;
502
503 if (index.data(KisTimeBasedItemModel::SpecialKeyframeExists).toBool()) {
504 QRect itemRect = m_d->itemDelegate->itemRect(index);
505
506 if (itemRect.intersects(rect)) {
507 selection.select(index, index);
508 }
509 }
510 }
511 }
512
513 if (!selection.contains(selectionModel()->currentIndex()) && selection.size() > 0) {
514 selectionModel()->setCurrentIndex(selection.first().topLeft(), flags);
515 }
516
517 selectionModel()->select(selection, flags);
518 activated(selectionModel()->currentIndex());
519}

References isIndexHidden(), m_d, and KisTimeBasedItemModel::SpecialKeyframeExists.

◆ slotDataAdded

void KisAnimCurvesView::slotDataAdded ( const QModelIndex & index)
privateslot

Definition at line 829 of file KisAnimCurvesView.cpp.

830{
831 const qreal lastVisibleValue = m_d->verticalHeader->visibleValueMax();
832 const qreal firstVisibleValue = m_d->verticalHeader->visibleValueMin();
833
834 qreal value = index.data(KisAnimCurvesModel::ScalarValueRole).toReal();
835 if ( value < firstVisibleValue || value > lastVisibleValue) {
836 qreal min, max;
837 findExtremes(&min, &max);
838 qreal padding = (max - min) * 0.1;
839 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
840 viewport()->update();
841 }
842
843 selectionModel()->clear();
844 selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
845}
void findExtremes(qreal *minimum, qreal *maximum)

References findExtremes(), m_d, KisAnimCurvesModel::ScalarValueRole, and value().

◆ slotDataChanged

void KisAnimCurvesView::slotDataChanged ( const QModelIndex & topLeft,
const QModelIndex & bottomRight )
privateslot

Definition at line 811 of file KisAnimCurvesView.cpp.

812{
813 Q_UNUSED(topLeft);
814 Q_UNUSED(bottomRight);
815
816 viewport()->update();
817
818 // this forces the horizontal ruler to refresh. Repaint() doesn't do it for some reason
819 // If you remove this, scrubbing the timeline will probably stop updating the indicator
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());
822
823 if (selectionModel()->selection().count() != 0 &&
824 selectionModel()->currentIndex().isValid()) {
825 Q_EMIT activeDataChanged(selectionModel()->currentIndex());
826 }
827}

References activeDataChanged(), and m_d.

◆ slotHeaderDataChanged

void KisAnimCurvesView::slotHeaderDataChanged ( Qt::Orientation orientation,
int first,
int last )
privateslot

Definition at line 847 of file KisAnimCurvesView.cpp.

848{
849 Q_UNUSED(orientation);
850 Q_UNUSED(first);
851 Q_UNUSED(last);
852 viewport()->update();
853}

◆ slotRowsChanged

void KisAnimCurvesView::slotRowsChanged ( const QModelIndex & parentIndex,
int first,
int last )
privateslot

Definition at line 802 of file KisAnimCurvesView.cpp.

803{
804 Q_UNUSED(parentIndex);
805 Q_UNUSED(first);
806 Q_UNUSED(last);
808 viewport()->update();
809}

References zoomToFitChannel().

◆ slotScrollerStateChanged

void KisAnimCurvesView::slotScrollerStateChanged ( QScroller::State state)
inlineslot

Definition at line 63 of file KisAnimCurvesView.h.

KRITAWIDGETUTILS_EXPORT void updateCursor(QWidget *source, QScroller::State state)

References KisKineticScroller::updateCursor().

◆ slotUpdateHorizontalScrollbarSize

void KisAnimCurvesView::slotUpdateHorizontalScrollbarSize ( )
privateslot

Definition at line 863 of file KisAnimCurvesView.cpp.

864{
865 if (m_d->model) {
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);
872 }
873}

References m_d.

◆ slotUpdateInfiniteFramesCount

void KisAnimCurvesView::slotUpdateInfiniteFramesCount ( )
privateslot

Definition at line 855 of file KisAnimCurvesView.cpp.

856{
857 if (m_d->model) {
858 const int lastColumn = m_d->horizontalHeader->estimateLastVisibleColumn();
859 m_d->model->setLastVisibleFrame(lastColumn);
860 }
861}

References m_d.

◆ updateGeometries

void KisAnimCurvesView::updateGeometries ( )
overrideprotectedslot

Definition at line 783 of file KisAnimCurvesView.cpp.

784{
785 int topMargin = qMax(m_d->horizontalHeader->minimumHeight(),
786 m_d->horizontalHeader->sizeHint().height());
787
788 int leftMargin = m_d->verticalHeader->sizeHint().width();
789
790 setViewportMargins(leftMargin, topMargin, 0, 0);
791
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());
795 if (m_d->model) {
797 }
798
799 QAbstractItemView::updateGeometries();
800}

References m_d, and slotUpdateInfiniteFramesCount().

◆ verticalOffset()

int KisAnimCurvesView::verticalOffset ( ) const
overrideprotected

Definition at line 478 of file KisAnimCurvesView.cpp.

479{
480 return m_d->verticalHeader->valueOffset();
481}

References m_d.

◆ visualRect()

QRect KisAnimCurvesView::visualRect ( const QModelIndex & index) const
override

Definition at line 179 of file KisAnimCurvesView.cpp.

180{
181 return m_d->itemDelegate->itemRect(index);
182}

References m_d.

◆ visualRegionForSelection()

QRegion KisAnimCurvesView::visualRegionForSelection ( const QItemSelection & selection) const
overrideprotected

Definition at line 521 of file KisAnimCurvesView.cpp.

522{
523 QRegion region;
524
525 Q_FOREACH(QModelIndex index, selection.indexes()) {
526 region += m_d->itemDelegate->visualRect(index);
527 }
528
529 return region;
530}

References m_d.

◆ zoomToFitChannel

void KisAnimCurvesView::zoomToFitChannel ( )
slot

Definition at line 969 of file KisAnimCurvesView.cpp.

970{
971 if (!model()) return;
972
973 const int channels = model()->rowCount();
974
975 qreal min = 0;
976 qreal max = min;
977
978 for (int channel = 0; channel < channels; channel++) {
979 QModelIndex index = m_d->model->index(channel, 0);
980 QVariant variant = m_d->model->data(index, KisAnimCurvesModel::ChannelLimits);
981
982 if (!variant.isValid())
983 continue;
984
985 ChannelLimitsMetatype limits = variant.value<ChannelLimitsMetatype>();
986 min = qMin(limits.first, min);
987 max = qMax(limits.second, max);
988 }
989
990 if (min == max)
991 {
993 return;
994 }
995
996 const qreal padding = (max - min) * 0.1;
997 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
998 viewport()->update();
999}

References KisAnimCurvesModel::ChannelLimits, m_d, and zoomToFitCurve().

◆ zoomToFitCurve

void KisAnimCurvesView::zoomToFitCurve ( )
slot

Definition at line 957 of file KisAnimCurvesView.cpp.

958{
959 if (!model()) return;
960
961 qreal min, max;
962 findExtremes(&min, &max);
963
964 const qreal padding = (min != max) ? (max - min) * 0.1 : 10.0f;
965 m_d->verticalHeader->zoomToFitRange(min - padding, max + padding);
966 viewport()->update();
967}

References findExtremes(), and m_d.

Member Data Documentation

◆ m_d

const QScopedPointer<Private> KisAnimCurvesView::m_d
private

Definition at line 78 of file KisAnimCurvesView.h.


The documentation for this class was generated from the following files: