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

Krita's Animation Curves Docker. This is the GUI heart of Krita's scalar animation workflow. More...

#include <KisAnimCurvesDocker.h>

+ Inheritance diagram for KisAnimCurvesDocker:

Classes

struct  Private
 

Public Slots

void handleFrameRateChange ()
 
void slotNodeActivated (KisNodeSP node)
 
void slotScrollerStateChanged (QScroller::State state)
 
void updateFrameRegister ()
 

Public Member Functions

 KisAnimCurvesDocker ()
 
QString observerName () override
 
void setCanvas (KoCanvasBase *canvas) override
 
void setPlaybackEngine (KisPlaybackEngine *playbackEngine)
 
void setViewManager (KisViewManager *kisview) override
 
void unsetCanvas () override
 
 ~KisAnimCurvesDocker () override
 
- Public Member Functions inherited from KisMainwindowObserver
 KisMainwindowObserver ()
 
 ~KisMainwindowObserver () override
 
- Public Member Functions inherited from KoCanvasObserverBase
 KoCanvasObserverBase ()
 
KoCanvasBaseobservedCanvas () const
 
void setObservedCanvas (KoCanvasBase *canvas)
 
void unsetObservedCanvas ()
 
virtual ~KoCanvasObserverBase ()
 

Private Slots

void requestChannelMenuAt (const QPoint &point)
 
void resetChannelTreeSelection ()
 
void slotActiveNodeUpdate (const QModelIndex index)
 
void slotAddAllEnabledKeys ()
 
void slotAddOpacityKey ()
 
void slotListRowsInserted (const QModelIndex &parentIndex, int first, int last)
 
void slotRemoveOpacityKey ()
 
void slotRemoveSelectedKeys ()
 
void slotUpdateIcons ()
 
void slotValueRegisterChanged (double value)
 

Private Member Functions

void addKeyframeCommandToParent (const QString &channelIdentity, KUndo2Command *parentCMD)
 
void addKeyframeQuick (const QString &channelIdentity)
 
void removeKeyframe (const QString &channel)
 

Private Attributes

const QScopedPointer< Privatem_d
 

Additional Inherited Members

Detailed Description

Krita's Animation Curves Docker. This is the GUI heart of Krita's scalar animation workflow.

Definition at line 77 of file KisAnimCurvesDocker.h.

Constructor & Destructor Documentation

◆ KisAnimCurvesDocker()

KisAnimCurvesDocker::KisAnimCurvesDocker ( )

Definition at line 263 of file KisAnimCurvesDocker.cpp.

264 : QDockWidget(i18n("Animation Curves"))
265 , m_d(new Private(this))
266{
267 QWidget *mainWidget = new QWidget(0);
268 mainWidget->setLayout(new QVBoxLayout());
269 setWidget(mainWidget);
270
271 QSplitter *mainSplitter = new QSplitter(this);
272 mainWidget->layout()->addWidget(mainSplitter);
273
274 { // Channel Tree..
275 m_d->channelTreeView->setModel(m_d->channelTreeModel);
276 m_d->channelTreeView->setHeaderHidden(true);
278 m_d->channelTreeView->setItemDelegate(listDelegate);
279
280 //Right click menu configuration for Channel Tree
281 m_d->channelTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
282 connect(m_d->channelTreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(requestChannelMenuAt(QPoint)));
283
284 m_d->channelTreeMenuChannels->addSection(i18n("Channel Operations"));
285 m_d->channelTreeMenuLayers->addSection(i18n("Layer Operations"));
286
287 { //Channels Menu
288 QAction* action = new QAction(i18n("Reset Channel"), this);
289 connect(action, SIGNAL(triggered(bool)), this, SLOT(resetChannelTreeSelection()));
290 m_d->channelTreeMenuChannels->addAction(action);
291 }
292
293 { //Layers Menu
294 QAction* action = new QAction(i18n("Reset All Channels"), this);
295 connect(action, SIGNAL(triggered(bool)), this, SLOT(resetChannelTreeSelection()));
296 m_d->channelTreeMenuLayers->addAction(action);
297 }
298 }
299
300 { // Curves View..
301 m_d->curvesView->setModel(m_d->curvesModel);
302 }
303
304 mainSplitter->addWidget(m_d->channelTreeView);
305 mainSplitter->setStretchFactor(0, 1);
306 mainSplitter->addWidget(m_d->curvesView);
307 mainSplitter->setStretchFactor(1, 10);
308
309 // Kinetic Scrolling..
310 QScroller *scroller = KisKineticScroller::createPreconfiguredScroller(m_d->channelTreeView);
311 if (scroller){
312 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
313 this, SLOT(slotScrollerStateChanged(QScroller::State)));
314 }
315
316 connect(m_d->channelTreeModel, &KisAnimCurvesChannelsModel::rowsInserted,
318
319 // Titlebar Widget..
320 setTitleBarWidget(m_d->titlebar);
321 setEnabled(false);
322
323 connect(m_d->titlebar->btnOnionSkinsMenu, &QToolButton::released, [this](){
324 if (m_d->mainWindow) {
325 QDockWidget *docker = m_d->mainWindow->dockWidget("OnionSkinsDocker");
326 if (docker) {
327 docker->setVisible(!docker->isVisible());
328 }
329 }
330 });
331
332 connect(m_d->titlebar->btnZoomHori, &KisZoomButton::zoom, [this](qreal zoomDelta){
333 if (m_d->curvesView) {
334 m_d->curvesView->changeZoom(Qt::Horizontal, zoomDelta);
335 }
336 });
337
338 connect(m_d->titlebar->btnZoomVert, &KisZoomButton::zoom, [this](qreal zoomDelta){
339 if (m_d->curvesView) {
340 m_d->curvesView->changeZoom(Qt::Vertical, zoomDelta);
341 }
342 });
343
344 connect(m_d->curvesView, SIGNAL(activated(QModelIndex)), this, SLOT(slotActiveNodeUpdate(QModelIndex)));
345 connect(m_d->curvesView, SIGNAL(activeDataChanged(QModelIndex)), this, SLOT(slotActiveNodeUpdate(QModelIndex)));
346 connect(m_d->titlebar->sbValueRegister, SIGNAL(valueChanged(double)), this, SLOT(slotValueRegisterChanged(double)));
347
348 {
349 using namespace KisWidgetConnectionUtils;
350 connectControl(m_d->titlebar->sbSpeed, &m_d->controlsModel, "playbackSpeedDenorm");
351 }
352
353 // Watch for KisPlaybackEngine changes and initialize current one..
355 setPlaybackEngine(KisPart::instance()->playbackEngine());
356}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void slotListRowsInserted(const QModelIndex &parentIndex, int first, int last)
const QScopedPointer< Private > m_d
void slotActiveNodeUpdate(const QModelIndex index)
void setPlaybackEngine(KisPlaybackEngine *playbackEngine)
void requestChannelMenuAt(const QPoint &point)
void slotScrollerStateChanged(QScroller::State state)
void slotValueRegisterChanged(double value)
static KisPart * instance()
Definition KisPart.cpp:131
void playbackEngineChanged(KisPlaybackEngine *newPlaybackEngine)
void zoom(qreal delta)
KRITAWIDGETUTILS_EXPORT QScroller * createPreconfiguredScroller(QAbstractScrollArea *target)
void connectControl(KisCompositeOpListWidget *widget, QObject *source, const char *property)

References connect(), KisKineticScroller::createPreconfiguredScroller(), m_d, requestChannelMenuAt(), resetChannelTreeSelection(), slotListRowsInserted(), and slotScrollerStateChanged().

◆ ~KisAnimCurvesDocker()

KisAnimCurvesDocker::~KisAnimCurvesDocker ( )
override

Definition at line 358 of file KisAnimCurvesDocker.cpp.

359{}

Member Function Documentation

◆ addKeyframeCommandToParent()

void KisAnimCurvesDocker::addKeyframeCommandToParent ( const QString & channelIdentity,
KUndo2Command * parentCMD )
private

Definition at line 566 of file KisAnimCurvesDocker.cpp.

567{
568 if (!m_d->canvas) return;
569
571 if (!node) return;
572
573 const int time = m_d->canvas->image()->animationInterface()->currentTime();
574 KisAnimUtils::createKeyframeCommand(m_d->canvas->image(), node, channelIdentity, time, false, parentCMD);
575}
KisImageWSP image() const
KisViewManager * viewManager() const
KisImageAnimationInterface * animationInterface() const
KisNodeSP activeNode()
KUndo2Command * createKeyframeCommand(KisImageSP image, KisNodeSP node, const QString &channelId, int time, bool copy, KUndo2Command *parentCommand)
KisCanvas2 * canvas

References KisViewManager::activeNode(), KisImage::animationInterface(), Private::canvas, KisAnimUtils::createKeyframeCommand(), KisImageAnimationInterface::currentTime(), KisCanvas2::image(), m_d, and KisCanvas2::viewManager().

◆ addKeyframeQuick()

void KisAnimCurvesDocker::addKeyframeQuick ( const QString & channelIdentity)
private

Definition at line 577 of file KisAnimCurvesDocker.cpp.

578{
579 if (!m_d->canvas) return;
580
582 if (!node) return;
583
584 const int time = m_d->canvas->image()->animationInterface()->currentTime();
585 KisAnimUtils::createKeyframeLazy(m_d->canvas->image(), node, channelIdentity, time, false);
586}
void createKeyframeLazy(KisImageSP image, KisNodeSP node, const QString &channelId, int time, bool copy)

References KisViewManager::activeNode(), KisImage::animationInterface(), Private::canvas, KisAnimUtils::createKeyframeLazy(), KisImageAnimationInterface::currentTime(), KisCanvas2::image(), m_d, and KisCanvas2::viewManager().

◆ handleFrameRateChange

void KisAnimCurvesDocker::handleFrameRateChange ( )
slot

Definition at line 640 of file KisAnimCurvesDocker.cpp.

641{
642 if (!m_d->canvas || !m_d->canvas->image()) return;
643
644 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
645 m_d->titlebar->sbFrameRate->setValue(animInterface->framerate());
646}

References KisImage::animationInterface(), KisImageAnimationInterface::framerate(), KisImageAnimationInterface::image(), and m_d.

◆ observerName()

QString KisAnimCurvesDocker::observerName ( )
inlineoverridevirtual

Reimplemented from KoCanvasObserverBase.

Definition at line 84 of file KisAnimCurvesDocker.h.

84{ return "AnimationCurveDocker"; }

◆ removeKeyframe()

void KisAnimCurvesDocker::removeKeyframe ( const QString & channel)
private

Definition at line 588 of file KisAnimCurvesDocker.cpp.

589{
590 if (!m_d->canvas) return;
591
593 if (!node) return;
594
595 QItemSelectionModel* selectionModel = m_d->curvesView->selectionModel();
596 QModelIndexList selected = selectionModel ? selectionModel->selectedIndexes() : QModelIndexList();
597
598 if (selected.count() > 0) {
599 Q_FOREACH(const QModelIndex& selection, selected) {
600 KisAnimUtils::removeKeyframe(m_d->canvas->image(), node, channel, selection.column());
601 }
602 } else {
603 const int time = m_d->canvas->image()->animationInterface()->currentTime();
604 KisAnimUtils::removeKeyframe(m_d->canvas->image(), node, channel, time);
605 }
606}
QList< QModelIndex > QModelIndexList
Definition LayerBox.h:41
void removeKeyframe(KisImageSP image, KisNodeSP node, const QString &channel, int time)

References KisViewManager::activeNode(), Private::canvas, m_d, KisAnimUtils::removeKeyframe(), and KisCanvas2::viewManager().

◆ requestChannelMenuAt

void KisAnimCurvesDocker::requestChannelMenuAt ( const QPoint & point)
privateslot

Definition at line 795 of file KisAnimCurvesDocker.cpp.

796{
797 if (m_d->channelTreeView->selectionModel()->selectedIndexes().size() == 0) {
798 return;
799 }
800 QModelIndex selected = m_d->channelTreeView->selectionModel()->selectedIndexes().first();
801
802 if (selected.data(KisAnimCurvesChannelsModel::CurveRole).toBool()) {
803 m_d->channelTreeMenuChannels->popup(m_d->channelTreeView->mapToGlobal(point));
804 } else {
805 m_d->channelTreeMenuLayers->popup(m_d->channelTreeView->mapToGlobal(point));
806 }
807}

References KisAnimCurvesChannelsModel::CurveRole, and m_d.

◆ resetChannelTreeSelection

void KisAnimCurvesDocker::resetChannelTreeSelection ( )
privateslot

Definition at line 809 of file KisAnimCurvesDocker.cpp.

810{
811 QList<QModelIndex> selected = m_d->channelTreeView->selectionModel()->selectedIndexes();
812 Q_FOREACH( const QModelIndex& index, selected) {
813 m_d->channelTreeModel->reset(index);
814 }
815}

References m_d.

◆ setCanvas()

void KisAnimCurvesDocker::setCanvas ( KoCanvasBase * canvas)
overridevirtual

re-implement this method in your canvas observer. It will be called whenever a canvas becomes active. Note that you are responsible for not connecting more than one time to the signals of a canvas or any of the QObjects you can access through the canvas.

Implements KoCanvasObserverBase.

Definition at line 361 of file KisAnimCurvesDocker.cpp.

362{
363 if (canvas && m_d->canvas == canvas) return;
364
365 if (m_d->canvas) {
366 m_d->canvasConnections.clear();
367 m_d->canvas->disconnectCanvasObserver(this);
368 m_d->channelTreeModel->selectedNodesChanged(KisNodeList());
369 m_d->canvas->animationState()->disconnect(this);
370 m_d->titlebar->transport->disconnect(m_d->canvas->animationState());
371 m_d->titlebar->transport->setPlaying(false);
372 m_d->titlebar->sbFrameRegister->disconnect(m_d->canvas->animationState());
373
374 if (m_d->canvas->image()) {
375 m_d->canvas->image()->animationInterface()->disconnect(this);
376 m_d->titlebar->sbStartFrame->disconnect(m_d->canvas->image()->animationInterface());
377 m_d->titlebar->sbEndFrame->disconnect(m_d->canvas->image()->animationInterface());
378 m_d->titlebar->sbFrameRate->disconnect(m_d->canvas->image()->animationInterface());
379 }
380
381 m_d->curvesModel->setImage(0);
382 }
383
384 m_d->canvas = dynamic_cast<KisCanvas2*>(canvas);
385 setEnabled(m_d->canvas != 0);
386
387 if (m_d->canvas) {
388 KisDocument *doc = static_cast<KisDocument*>(m_d->canvas->imageView()->document());
389 KisShapeController *kritaShapeController = dynamic_cast<KisShapeController*>(doc->shapeController());
390 m_d->channelTreeModel->setDummiesFacade(kritaShapeController);
391
392 m_d->curvesModel->setImage(m_d->canvas->image());
393 m_d->curvesModel->setFrameCache(m_d->canvas->frameCache());
394 m_d->curvesModel->setAnimationPlayer(m_d->canvas->animationState());
395
396 m_d->canvasConnections.addConnection(
397 m_d->canvas->viewManager()->nodeManager(), SIGNAL(sigUiNeedChangeSelectedNodes(KisNodeList)),
398 m_d->channelTreeModel, SLOT(selectedNodesChanged(KisNodeList))
399 );
400
401 m_d->canvasConnections.addConnection(
402 m_d->canvas->viewManager()->nodeManager(), SIGNAL(sigNodeActivated(KisNodeSP)),
403 this, SLOT(slotNodeActivated(KisNodeSP))
404 );
405
406 m_d->channelTreeModel->clear();
407 m_d->channelTreeModel->selectedNodesChanged(m_d->canvas->viewManager()->nodeManager()->selectedNodes());
408
409 { // Reinitialize titlebar widgets..
410 KisSignalsBlocker blocker(m_d->titlebar->sbStartFrame,
411 m_d->titlebar->sbEndFrame,
412 m_d->titlebar->sbFrameRate,
413 m_d->titlebar->sbFrameRegister,
414 m_d->titlebar->sbValueRegister);
415
416 KisImageAnimationInterface *animinterface = m_d->canvas->image()->animationInterface();
417 m_d->titlebar->sbStartFrame->setValue(animinterface->documentPlaybackRange().start());
418 m_d->titlebar->sbEndFrame->setValue(animinterface->documentPlaybackRange().end());
419 m_d->titlebar->sbFrameRate->setValue(animinterface->framerate());
420 m_d->titlebar->sbFrameRegister->setValue(animinterface->currentTime());
421
422 QModelIndex activeIndex = m_d->curvesView->currentIndex();
423 m_d->titlebar->sbValueRegister->setEnabled(activeIndex.isValid());
424 m_d->titlebar->sbValueRegister->setValue( activeIndex.isValid() ?
425 activeIndex.data(KisAnimCurvesModel::ScalarValueRole).toReal() : 0.0f);
426 }
427
428 m_d->titlebar->transport->setPlaying(m_d->canvas->animationState()->playbackState() == PlaybackState::PLAYING);
429
430 connect(m_d->titlebar->sbFrameRate, SIGNAL(valueChanged(int)), m_d->canvas->image()->animationInterface(), SLOT(setFramerate(int)));
431 connect(m_d->titlebar->sbStartFrame, SIGNAL(valueChanged(int)), m_d->canvas->image()->animationInterface(), SLOT(setDocumentRangeStartFrame(int)));
432 connect(m_d->titlebar->sbEndFrame, SIGNAL(valueChanged(int)), m_d->canvas->image()->animationInterface(), SLOT(setDocumentRangeEndFrame(int)));
433
434 connect(m_d->canvas->animationState(), &KisCanvasAnimationState::sigPlaybackStateChanged, m_d->titlebar->transport, [this](PlaybackState p_state){
435 m_d->titlebar->transport->setPlaying(p_state == PlaybackState::PLAYING);
436 m_d->titlebar->sbFrameRegister->setDisabled(p_state == PlaybackState::PLAYING);
437
438 if (p_state == PlaybackState::STOPPED) {
439 updateFrameRegister();
440 }
441 });
442
443 connect(m_d->canvas->animationState(), SIGNAL(sigFrameChanged()), this, SLOT(updateFrameRegister()));
444
445 connect(m_d->canvas->image()->animationInterface(), SIGNAL(sigUiTimeChanged(int)), this, SLOT(updateFrameRegister()));
446
447 connect(m_d->canvas->image()->animationInterface(), &KisImageAnimationInterface::sigPlaybackRangeChanged, this, [this]() {
448 if (!m_d->canvas || !m_d->canvas->image()) return;
449
450 KisImageAnimationInterface *animInterface = m_d->canvas->image()->animationInterface();
451
452 m_d->titlebar->sbStartFrame->setValue(animInterface->documentPlaybackRange().start());
453 m_d->titlebar->sbEndFrame->setValue(animInterface->documentPlaybackRange().end());
454 });
455
456 connect(m_d->canvas->image()->animationInterface(), SIGNAL(sigFramerateChanged()), this, SLOT(handleFrameRateChange()));
457
458 m_d->controlsModel.connectAnimationState(m_d->canvas->animationState());
459 }
460}
void slotNodeActivated(KisNodeSP node)
void sigPlaybackStateChanged(PlaybackState state)
KisShapeController * shapeController
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
void setImage(KisImageWSP image, KisNodeSP activeNode) override
int start() const
int end() const
QList< KisNodeSP > KisNodeList
Definition kis_types.h:264

References KisImage::animationInterface(), Private::canvas, connect(), KisImageAnimationInterface::currentTime(), KisImageAnimationInterface::documentPlaybackRange(), KisTimeSpan::end(), KisImageAnimationInterface::framerate(), handleFrameRateChange(), KisImageAnimationInterface::image(), m_d, PLAYING, KisAnimCurvesModel::ScalarValueRole, KisShapeController::setImage(), KisDocument::shapeController, KisImageAnimationInterface::sigPlaybackRangeChanged(), KisCanvasAnimationState::sigPlaybackStateChanged(), slotNodeActivated(), KisTimeSpan::start(), and updateFrameRegister().

◆ setPlaybackEngine()

void KisAnimCurvesDocker::setPlaybackEngine ( KisPlaybackEngine * playbackEngine)

Definition at line 549 of file KisAnimCurvesDocker.cpp.

550{
551 if (!playbackEngine) return;
552
553 // Connect transport controls..
554 connect(m_d->titlebar->transport, SIGNAL(skipBack()), playbackEngine, SLOT(previousKeyframe()));
555 connect(m_d->titlebar->transport, SIGNAL(back()), playbackEngine, SLOT(previousFrame()));
556 connect(m_d->titlebar->transport, SIGNAL(stop()), playbackEngine, SLOT(stop()));
557 connect(m_d->titlebar->transport, SIGNAL(playPause()), playbackEngine, SLOT(playPause()));
558 connect(m_d->titlebar->transport, SIGNAL(forward()), playbackEngine, SLOT(nextFrame()));
559 connect(m_d->titlebar->transport, SIGNAL(skipForward()), playbackEngine, SLOT(nextKeyframe()));
560
561 connect(m_d->titlebar->sbFrameRegister, SIGNAL(valueChanged(int)), playbackEngine, SLOT(seek(int)));
562
563 m_d->controlsModel.connectPlaybackEngine(playbackEngine);
564}
QAction * back(const QObject *recvr, const char *slot, QObject *parent)
QAction * forward(const QObject *recvr, const char *slot, QObject *parent)

References connect(), and m_d.

◆ setViewManager()

void KisAnimCurvesDocker::setViewManager ( KisViewManager * kisview)
overridevirtual

Implements KisMainwindowObserver.

Definition at line 467 of file KisAnimCurvesDocker.cpp.

468{
469 m_d->mainWindow = view->mainWindow();
470
471 connect(view->mainWindow(), SIGNAL(themeChanged()), this, SLOT(slotUpdateIcons()));
473
474 KisActionManager* actionManager = view->actionManager();
475
476 KisAction* action = actionManager->createAction("add_scalar_keyframes");
477 action->setIcon(KisIconUtils::loadIcon("keyframe-add"));
478 connect(action, SIGNAL(triggered(bool)),
479 this, SLOT(slotAddAllEnabledKeys()));
480 m_d->titlebar->btnAddKey->setDefaultAction(action);
481 m_d->titlebar->btnAddKey->setIconSize(QSize(22, 22));
482
483 action = actionManager->createAction("remove_scalar_keyframe");
484 action->setIcon(KisIconUtils::loadIcon("keyframe-remove"));
485 connect(action, SIGNAL(triggered(bool)),
486 this, SLOT(slotRemoveSelectedKeys()));
487 m_d->titlebar->btnRemoveKey->setDefaultAction(action);
488 m_d->titlebar->btnRemoveKey->setIconSize(QSize(22, 22));
489
490 action = actionManager->createAction("interpolation_constant");
491 action->setIcon(KisIconUtils::loadIcon("interpolation_constant"));
492 action->setToolTip(i18n("Hold constant value. No interpolation."));
493 connect(action, &KisAction::triggered,
495 m_d->titlebar->btnGroupInterpolation->addAction(action);
496
497 action = actionManager->createAction("interpolation_linear");
498 action->setIcon(KisIconUtils::loadIcon("interpolation_linear"));
499 action->setToolTip(i18n("Linear interpolation."));
500 connect(action, &KisAction::triggered,
502 m_d->titlebar->btnGroupInterpolation->addAction(action);
503
504 action = actionManager->createAction("interpolation_bezier");
505 action->setIcon(KisIconUtils::loadIcon("interpolation_bezier"));
506 action->setToolTip(i18n("Bezier curve interpolation."));
507 connect(action, &KisAction::triggered,
509 m_d->titlebar->btnGroupInterpolation->addAction(action);
510
511 action = actionManager->createAction("tangents_sharp");
512 action->setIcon(KisIconUtils::loadIcon("interpolation_sharp"));
513 action->setToolTip(i18n("Sharp interpolation tangents."));
514 connect(action, &KisAction::triggered,
516 m_d->titlebar->btnGroupTangents->addAction(action);
517
518 action = actionManager->createAction("tangents_smooth");
519 action->setIcon(KisIconUtils::loadIcon("interpolation_smooth"));
520 action->setToolTip(i18n("Smooth interpolation tangents."));
521 connect(action, &KisAction::triggered,
523 m_d->titlebar->btnGroupTangents->addAction(action);
524
525 action = actionManager->createAction("zoom_to_fit_range");
526 action->setIcon(KisIconUtils::loadIcon("zoom-fit"));
527 action->setToolTip(i18n("Zoom view to fit channel range."));
528 connect(action, &KisAction::triggered,
530 m_d->titlebar->btnGroupZoomFit->addAction(action);
531
532 action = actionManager->createAction("zoom_to_fit_curve");
533 action->setIcon(KisIconUtils::loadIcon("zoom-fit-curve"));
534 action->setToolTip(i18n("Zoom view to fit curve."));
535 connect(action, &KisAction::triggered,
537 m_d->titlebar->btnGroupZoomFit->addAction(action);
538
539 {
540 action = actionManager->createAction("drop_frames");
541 m_d->titlebar->btnDropFrames->setDefaultAction(action);
542 m_d->titlebar->btnDropFrames->setIconSize(QSize(22, 22));
543
544 using namespace KisWidgetConnectionUtils;
545 connectControl(action, &m_d->controlsModel, "dropFramesMode");
546 }
547}
A KisActionManager class keeps track of KisActions. These actions are always associated with the GUI....
KisAction * createAction(const QString &name)
QIcon loadIcon(const QString &name)

References KisViewManager::actionManager(), KisAnimCurvesView::applyBezierMode(), KisAnimCurvesView::applyConstantMode(), KisAnimCurvesView::applyLinearMode(), KisAnimCurvesView::applySharpMode(), KisAnimCurvesView::applySmoothMode(), connect(), KisActionManager::createAction(), KisIconUtils::loadIcon(), m_d, KisViewManager::mainWindow(), slotAddAllEnabledKeys(), slotRemoveSelectedKeys(), slotUpdateIcons(), KisAnimCurvesView::zoomToFitChannel(), and KisAnimCurvesView::zoomToFitCurve().

◆ slotActiveNodeUpdate

void KisAnimCurvesDocker::slotActiveNodeUpdate ( const QModelIndex index)
privateslot

Definition at line 782 of file KisAnimCurvesDocker.cpp.

783{
784 KisSignalsBlocker blockSignal(m_d->titlebar->sbValueRegister);
785
786 if (index.isValid() && m_d->curvesView->indexHasKey(index)) {
787 QVariant variant = m_d->curvesModel->data(index, KisAnimCurvesModel::ScalarValueRole);
788 m_d->titlebar->sbValueRegister->setEnabled(variant.isValid());
789 m_d->titlebar->sbValueRegister->setValue(variant.isValid() ? variant.toReal() : 0.0);
790 } else {
791 m_d->titlebar->sbValueRegister->setEnabled(false);
792 }
793}

References m_d, and KisAnimCurvesModel::ScalarValueRole.

◆ slotAddAllEnabledKeys

void KisAnimCurvesDocker::slotAddAllEnabledKeys ( )
privateslot

Definition at line 652 of file KisAnimCurvesDocker.cpp.

653{
654 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->canvas && m_d->canvas->viewManager());
655 // remember current node's opacity and set it once we create a new opacity keyframe
658
659 /* Once we start dealing with more scalar values,
660 * we should add a dropdown check-box set of actions that can
661 * enable and disable keys. For now, we will just consider all channels
662 * enabled. */
663 KUndo2Command* parentCMD = new KUndo2Command(kundo2_i18n("Add Scalar Keyframes"));
664
665 //This should eventually be a list of all currently enabled channels.
666 QList<KoID> ids = {
677 };
678
679 Q_FOREACH( const KoID& koid, ids ) {
680 if (node->supportsKeyframeChannel(koid.id())) {
681 addKeyframeCommandToParent(koid.id(), parentCMD);
682 }
683 }
684
685 if (m_d->canvas && m_d->canvas->image()) {
686 KisProcessingApplicator::runSingleCommandStroke(m_d->canvas->image(), parentCMD,
689 }
690}
void addKeyframeCommandToParent(const QString &channelIdentity, KUndo2Command *parentCMD)
static const KoID RotationY
static const KoID ScaleY
static const KoID RotationZ
static const KoID Opacity
static const KoID ScaleX
static const KoID RotationX
static const KoID PositionX
static const KoID PositionY
static const KoID ShearX
static const KoID ShearY
static void runSingleCommandStroke(KisImageSP image, KUndo2Command *cmd, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
runSingleCommandStroke creates a stroke and runs cmd in it. The text() field of cmd is used as a titl...
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
KUndo2MagicString kundo2_i18n(const char *text)
virtual bool supportsKeyframeChannel(const QString &id)

References KisViewManager::activeNode(), addKeyframeCommandToParent(), KisStrokeJobData::BARRIER, Private::canvas, KisStrokeJobData::EXCLUSIVE, KoID::id(), KIS_SAFE_ASSERT_RECOVER_RETURN, kundo2_i18n(), m_d, KisKeyframeChannel::Opacity, KisKeyframeChannel::PositionX, KisKeyframeChannel::PositionY, KisKeyframeChannel::RotationX, KisKeyframeChannel::RotationY, KisKeyframeChannel::RotationZ, KisProcessingApplicator::runSingleCommandStroke(), KisKeyframeChannel::ScaleX, KisKeyframeChannel::ScaleY, KisKeyframeChannel::ShearX, KisKeyframeChannel::ShearY, KisBaseNode::supportsKeyframeChannel(), and KisCanvas2::viewManager().

◆ slotAddOpacityKey

◆ slotListRowsInserted

void KisAnimCurvesDocker::slotListRowsInserted ( const QModelIndex & parentIndex,
int first,
int last )
privateslot

Definition at line 762 of file KisAnimCurvesDocker.cpp.

763{
764 // Auto-expand nodes on the tree
765 for (int r=first; r<=last; r++) {
766 QModelIndex index = m_d->channelTreeModel->index(r, 0, parentIndex);
767 m_d->channelTreeView->expand(index);
768 }
769}

References m_d.

◆ slotNodeActivated

◆ slotRemoveOpacityKey

◆ slotRemoveSelectedKeys

void KisAnimCurvesDocker::slotRemoveSelectedKeys ( )
privateslot

Definition at line 705 of file KisAnimCurvesDocker.cpp.

706{
707 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->canvas && m_d->canvas->viewManager());
708
711
712
713 QItemSelectionModel* selectionModel = m_d->curvesView->selectionModel();
714 QModelIndexList selected = selectionModel ? selectionModel->selectedIndexes() : QModelIndexList();
715
717
718 if (selected.count() > 0) {
719 Q_FOREACH(const QModelIndex& selection, selected) {
720 QVariant data = selection.data(KisAnimCurvesModel::ChannelIdentifier);
721
722 if (!data.isValid())
723 continue;
724
725 const QString identifier = data.toString();
726 const int time = selection.column();
727 framesToRemove.push_back(KisAnimUtils::FrameItem(node, identifier, time));
728 }
729 } else {
730 const int time = m_d->canvas->image()->animationInterface()->currentTime();
731 for(int channelIndex = 0; channelIndex < m_d->curvesModel->rowCount(); channelIndex++) {
732 QModelIndex chanIndex = m_d->curvesModel->index(channelIndex, time);
733 if (!chanIndex.isValid())
734 continue;
735
736 QVariant data = chanIndex.data(KisAnimCurvesModel::ChannelIdentifier);
737 if (!data.isValid())
738 continue;
739
740 const QString identifier = data.toString();
741 framesToRemove.push_back(KisAnimUtils::FrameItem(node, identifier, time));
742 }
743 }
744
745 if (m_d->canvas && m_d->canvas->image()) {
746 KisAnimUtils::removeKeyframes(m_d->canvas->image(), framesToRemove);
747 }
748}
void removeKeyframes(KisImageSP image, const FrameItemList &frames)

References KisViewManager::activeNode(), Private::canvas, KisAnimCurvesModel::ChannelIdentifier, KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, KisAnimUtils::removeKeyframes(), and KisCanvas2::viewManager().

◆ slotScrollerStateChanged

void KisAnimCurvesDocker::slotScrollerStateChanged ( QScroller::State state)
slot

Definition at line 608 of file KisAnimCurvesDocker.cpp.

609{
610 KisKineticScroller::updateCursor(m_d->channelTreeView, state);
611}
KRITAWIDGETUTILS_EXPORT void updateCursor(QWidget *source, QScroller::State state)

References m_d, and KisKineticScroller::updateCursor().

◆ slotUpdateIcons

void KisAnimCurvesDocker::slotUpdateIcons ( )
privateslot

Definition at line 648 of file KisAnimCurvesDocker.cpp.

649{
650}

◆ slotValueRegisterChanged

void KisAnimCurvesDocker::slotValueRegisterChanged ( double value)
privateslot

Definition at line 771 of file KisAnimCurvesDocker.cpp.

771 {
772 if (!m_d->curvesModel)
773 return;
774
775 QModelIndex current = m_d->curvesView->currentIndex();
776
777 if (current.isValid() && m_d->curvesView->indexHasKey(current)) {
778 m_d->curvesModel->setData(current, value, KisAnimCurvesModel::ScalarValueRole);
779 }
780}
float value(const T *src, size_t ch)

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

◆ unsetCanvas()

void KisAnimCurvesDocker::unsetCanvas ( )
overridevirtual

Re-implement to notify the observer that its canvas is no longer among the living. The daisies, it is pushing up. This means you don't have to disconnect, it's dead.

The old canvas should be deleted already, so if you stored a pointer to it, don't touch!

Note that currently there is a bug where in certain specific circumstances unsetCanvas can be called when it shouldn't, see for example KWStatisticsDocker for a workaround for this problem.

Implements KoCanvasObserverBase.

Definition at line 462 of file KisAnimCurvesDocker.cpp.

463{
464 setCanvas(0);
465}
void setCanvas(KoCanvasBase *canvas) override

References setCanvas().

◆ updateFrameRegister

void KisAnimCurvesDocker::updateFrameRegister ( )
slot

Definition at line 629 of file KisAnimCurvesDocker.cpp.

629 {
630 if (!m_d->canvas && !m_d->canvas->image()) {
631 return;
632 }
633
634 const int frame = m_d->canvas->animationState()->displayProxy()->activeFrame();
635
636 QSignalBlocker blocker(m_d->titlebar->sbFrameRegister);
637 m_d->titlebar->sbFrameRegister->setValue(frame);
638}

References m_d.

Member Data Documentation

◆ m_d

const QScopedPointer<Private> KisAnimCurvesDocker::m_d
private

Definition at line 123 of file KisAnimCurvesDocker.h.


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