Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/keyframenavigator.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/styleselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectkeyframe.h"
Toshihiro Shimizu 890ddd
#include "toonz/stageobjectutil.h"
manongjohn 4be4bb
#include "toonz/tapplication.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tfx.h"
Toshihiro Shimizu 890ddd
#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tspectrumparam.h"
Toshihiro Shimizu 890ddd
#include "ttonecurveparam.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
#include <qpixmap></qpixmap>
Toshihiro Shimizu 890ddd
#include <qicon></qicon>
Toshihiro Shimizu 890ddd
e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma warning(disable : 4251)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Campbell Barton 40cabe
#include <memory></memory>
Campbell Barton 40cabe
Toshihiro Shimizu 890ddd
#include <qaction></qaction>
Toshihiro Shimizu 890ddd
#include <qmouseevent></qmouseevent>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// KeyframeNavigator
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
KeyframeNavigator::KeyframeNavigator(QWidget *parent, TFrameHandle *frameHandle)
manongjohn 4be4bb
    : QToolBar(parent), m_frameHandle(frameHandle), m_panel(0) {
Shinya Kitaoka 120a6e
  setLayoutDirection(Qt::LeftToRight);
Toshihiro Shimizu 890ddd
shun_iwasawa 4a5f42
  setIconSize(QSize(18, 18));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setObjectName("keyFrameNavigator");
Toshihiro Shimizu 890ddd
shun-iwasawa 5b7b9f
  QPixmap emptyPrevPixmap(
shun-iwasawa 5b7b9f
      23, 23);  // set transparent icon to show button's background
Jeremy Bullock c82a0a
  emptyPrevPixmap.fill(Qt::transparent);
Jeremy Bullock c82a0a
  QIcon emptyPrevIcon(emptyPrevPixmap);
Jeremy Bullock c82a0a
Jeremy Bullock c82a0a
  m_actPreviewKey = new QAction(emptyPrevIcon, tr("Previous Key"), this);
Shinya Kitaoka 120a6e
  connect(m_actPreviewKey, SIGNAL(triggered()), SLOT(togglePrevKeyAct()));
Shinya Kitaoka 120a6e
  addAction(m_actPreviewKey);
shun-iwasawa 5b7b9f
  QWidget *prevWidget = widgetForAction(
shun-iwasawa 5b7b9f
      m_actPreviewKey);  // obtain a widget generated from QAction
Jeremy Bullock c82a0a
  prevWidget->setObjectName("PreviousKey");
Toshihiro Shimizu 890ddd
shun_iwasawa 4a5f42
  m_actKeyNo = new QAction(createQIcon("key_no"), tr("Set Key"), this);
Shinya Kitaoka 120a6e
  connect(m_actKeyNo, SIGNAL(triggered()), SLOT(toggleKeyAct()));
Shinya Kitaoka 120a6e
  addAction(m_actKeyNo);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_actKeyPartial =
shun_iwasawa 4a5f42
      new QAction(createQIcon("key_partial"), tr("Set Key"), this);
Shinya Kitaoka 120a6e
  connect(m_actKeyPartial, SIGNAL(triggered()), SLOT(toggleKeyAct()));
Shinya Kitaoka 120a6e
  addAction(m_actKeyPartial);
Toshihiro Shimizu 890ddd
shun_iwasawa 4a5f42
  m_actKeyTotal = new QAction(createQIcon("key_total"), tr("Set Key"), this);
Shinya Kitaoka 120a6e
  connect(m_actKeyTotal, SIGNAL(triggered()), SLOT(toggleKeyAct()));
Shinya Kitaoka 120a6e
  addAction(m_actKeyTotal);
Toshihiro Shimizu 890ddd
shun-iwasawa 5b7b9f
  QPixmap emptyNextPixmap(
shun-iwasawa 5b7b9f
      23, 23);  // set transparent icon to show button's background
Jeremy Bullock c82a0a
  emptyNextPixmap.fill(Qt::transparent);
Jeremy Bullock c82a0a
  QIcon emptyNextIcon(emptyNextPixmap);
Jeremy Bullock c82a0a
Jeremy Bullock c82a0a
  m_actNextKey = new QAction(emptyNextIcon, tr("Next Key"), this);
Shinya Kitaoka 120a6e
  connect(m_actNextKey, SIGNAL(triggered()), SLOT(toggleNextKeyAct()));
Shinya Kitaoka 120a6e
  addAction(m_actNextKey);
shun-iwasawa 5b7b9f
  QWidget *nextWidget =
shun-iwasawa 5b7b9f
      widgetForAction(m_actNextKey);  // obtain a widget generated from QAction
Jeremy Bullock c82a0a
  nextWidget->setObjectName("NextKey");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void KeyframeNavigator::update() {
Shinya Kitaoka 120a6e
  // Prev button
Shinya Kitaoka 120a6e
  if (hasPrev())
Shinya Kitaoka 120a6e
    m_actPreviewKey->setDisabled(false);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_actPreviewKey->setDisabled(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool isFullKey = isFullKeyframe();
Shinya Kitaoka 120a6e
  bool isKey     = isKeyframe();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (isKey && !isFullKey) {
Shinya Kitaoka 120a6e
    m_actKeyNo->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyTotal->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyPartial->setVisible(true);
Shinya Kitaoka 120a6e
    m_actKeyPartial->setDisabled(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (isFullKey) {
Shinya Kitaoka 120a6e
    m_actKeyNo->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyPartial->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyTotal->setVisible(true);
Shinya Kitaoka 120a6e
    m_actKeyTotal->setDisabled(false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!isKey && !isFullKey) {
Shinya Kitaoka 120a6e
    m_actKeyPartial->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyTotal->setVisible(false);
Shinya Kitaoka 120a6e
    m_actKeyNo->setVisible(true);
Shinya Kitaoka 120a6e
    m_actKeyNo->setDisabled(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Next button
Shinya Kitaoka 120a6e
  if (hasNext())
Shinya Kitaoka 120a6e
    m_actNextKey->setDisabled(false);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_actNextKey->setDisabled(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void KeyframeNavigator::showEvent(QShowEvent *e) {
Shinya Kitaoka 120a6e
  update();
Shinya Kitaoka 120a6e
  if (!m_frameHandle) return;
Shinya Kitaoka 120a6e
  connect(m_frameHandle, SIGNAL(frameSwitched()), this, SLOT(update()));
manongjohn 4be4bb
manongjohn 4be4bb
  connect(m_frameHandle, SIGNAL(triggerNextKeyframe(QWidget *)), this,
manongjohn 4be4bb
          SLOT(onNextKeyframe(QWidget *)));
manongjohn 4be4bb
  connect(m_frameHandle, SIGNAL(triggerPrevKeyframe(QWidget *)), this,
manongjohn 4be4bb
          SLOT(onPrevKeyframe(QWidget *)));
manongjohn 4be4bb
  if (!m_panel || m_panel == nullptr) {
manongjohn 4be4bb
    QWidget *panel = this->parentWidget();
manongjohn 4be4bb
    while (panel) {
manongjohn 4be4bb
      if (panel->windowType() == Qt::WindowType::SubWindow ||
manongjohn 4be4bb
          panel->windowType() == Qt::WindowType::Tool) {
manongjohn 4be4bb
        m_panel = panel;
manongjohn 4be4bb
        break;
manongjohn 4be4bb
      }
manongjohn 4be4bb
      panel = panel->parentWidget();
manongjohn 4be4bb
    }
manongjohn 4be4bb
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void KeyframeNavigator::hideEvent(QHideEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_frameHandle) return;
Shinya Kitaoka 120a6e
  disconnect(m_frameHandle);
manongjohn f5c90f
manongjohn f5c90f
  disconnect(m_frameHandle, SIGNAL(triggerNextKeyframe(QWidget *)), this,
manongjohn f5c90f
             SLOT(onNextKeyframe(QWidget *)));
manongjohn f5c90f
  disconnect(m_frameHandle, SIGNAL(triggerPrevKeyframe(QWidget *)), this,
manongjohn f5c90f
             SLOT(onPrevKeyframe(QWidget *)));
manongjohn f5c90f
  m_panel = nullptr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
manongjohn 4be4bb
void KeyframeNavigator::onNextKeyframe(QWidget *panel) {
manongjohn 4be4bb
  if (!m_panel || m_panel != panel) return;
manongjohn 4be4bb
  toggleNextKeyAct();
manongjohn 4be4bb
}
manongjohn 4be4bb
manongjohn 4be4bb
void KeyframeNavigator::onPrevKeyframe(QWidget *panel) {
manongjohn 4be4bb
  if (!m_panel || m_panel != panel) return;
manongjohn 4be4bb
  togglePrevKeyAct();
manongjohn 4be4bb
}
manongjohn 4be4bb
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ViewerKeyframeNavigator
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject *ViewerKeyframeNavigator::getStageObject() const {
Shinya Kitaoka 120a6e
  if (!m_xsheetHandle || !m_objectHandle) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStageObjectId objectId = m_objectHandle->getObjectId();
Shinya Kitaoka 120a6e
  TXsheet *xsh            = m_xsheetHandle->getXsheet();
Shinya Kitaoka 120a6e
  // Se e' una colonna sound non posso settare chiavi
Shinya Kitaoka 120a6e
  if (objectId.isColumn()) {
Shinya Kitaoka 120a6e
    TXshColumn *column = xsh->getColumn(objectId.getIndex());
Shinya Kitaoka 120a6e
    if (column && column->getSoundColumn()) return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return xsh->getStageObject(objectId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ViewerKeyframeNavigator::hasNext() const {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return false;
Shinya Kitaoka 120a6e
  int r0, r1;
Shinya Kitaoka 120a6e
  pegbar->getKeyframeRange(r0, r1);
Shinya Kitaoka 120a6e
  return r0 <= r1 && getCurrentFrame() < r1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ViewerKeyframeNavigator::hasPrev() const {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return false;
Shinya Kitaoka 120a6e
  int r0, r1;
Shinya Kitaoka 120a6e
  pegbar->getKeyframeRange(r0, r1);
Shinya Kitaoka 120a6e
  return r0 <= r1 && getCurrentFrame() > r0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ViewerKeyframeNavigator::hasKeyframes() const {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return false;
Shinya Kitaoka 120a6e
  int r0, r1;
Shinya Kitaoka 120a6e
  pegbar->getKeyframeRange(r0, r1);
Shinya Kitaoka 120a6e
  return r0 <= r1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ViewerKeyframeNavigator::isKeyframe() const {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return false;
Shinya Kitaoka 120a6e
  return pegbar->isKeyframe(getCurrentFrame());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ViewerKeyframeNavigator::isFullKeyframe() const {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return false;
Shinya Kitaoka 120a6e
  return pegbar->isFullKeyframe(getCurrentFrame());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ViewerKeyframeNavigator::toggle() {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return;
Shinya Kitaoka 120a6e
  int frame = getCurrentFrame();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (pegbar->isFullKeyframe(frame)) {
Shinya Kitaoka 120a6e
    TStageObject::Keyframe key = pegbar->getKeyframe(frame);
Shinya Kitaoka 120a6e
    pegbar->removeKeyframeWithoutUndo(frame);
Shinya Kitaoka 120a6e
    UndoRemoveKeyFrame *undo =
Shinya Kitaoka 120a6e
        new UndoRemoveKeyFrame(pegbar->getId(), frame, key, m_xsheetHandle);
Shinya Kitaoka 120a6e
    undo->setObjectHandle(m_objectHandle);
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    UndoSetKeyFrame *undo =
Shinya Kitaoka 120a6e
        new UndoSetKeyFrame(pegbar->getId(), frame, m_xsheetHandle);
Shinya Kitaoka 120a6e
    pegbar->setKeyframeWithoutUndo(frame);
Shinya Kitaoka 120a6e
    undo->setObjectHandle(m_objectHandle);
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_objectHandle->notifyObjectIdChanged(false);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ViewerKeyframeNavigator::goNext() {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return;
Shinya Kitaoka 120a6e
  int frame = getCurrentFrame();
Shinya Kitaoka 120a6e
  TStageObject::KeyframeMap keyframes;
Shinya Kitaoka 120a6e
  pegbar->getKeyframes(keyframes);
Shinya Kitaoka 120a6e
  TStageObject::KeyframeMap::iterator it;
Shinya Kitaoka 120a6e
  for (it = keyframes.begin(); it != keyframes.end(); ++it)
Shinya Kitaoka 120a6e
    if (it->first > frame) {
Shinya Kitaoka 120a6e
      setCurrentFrame(it->first);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ViewerKeyframeNavigator::goPrev() {
Shinya Kitaoka 120a6e
  TStageObject *pegbar = getStageObject();
Shinya Kitaoka 120a6e
  if (!pegbar) return;
Shinya Kitaoka 120a6e
  int frame = getCurrentFrame();
Shinya Kitaoka 120a6e
  TStageObject::KeyframeMap keyframes;
Shinya Kitaoka 120a6e
  pegbar->getKeyframes(keyframes);
Shinya Kitaoka 120a6e
  TStageObject::KeyframeMap::reverse_iterator it;
Shinya Kitaoka 120a6e
  for (it = keyframes.rbegin(); it != keyframes.rend(); ++it)
Shinya Kitaoka 120a6e
    if (it->first < frame) {
Shinya Kitaoka 120a6e
      setCurrentFrame(it->first);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ViewerKeyframeNavigator::showEvent(QShowEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_objectHandle) return;
Shinya Kitaoka 120a6e
  connect(m_objectHandle, SIGNAL(objectSwitched()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  connect(m_objectHandle, SIGNAL(objectChanged(bool)), this, SLOT(update()));
Shinya Kitaoka 120a6e
  KeyframeNavigator::showEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ViewerKeyframeNavigator::hideEvent(QHideEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_objectHandle) return;
Shinya Kitaoka 120a6e
  disconnect(m_objectHandle);
Shinya Kitaoka 120a6e
  KeyframeNavigator::hideEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UndoPaletteSetKeyFrame final : public TUndo {
Shinya Kitaoka 120a6e
  int m_frame;
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
  TPaletteHandle *m_paletteHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UndoPaletteSetKeyFrame(int styleId, int frame, TPaletteHandle *paletteHandle)
Shinya Kitaoka 120a6e
      : m_frame(frame), m_styleId(styleId), m_paletteHandle(paletteHandle) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override { setKeyFrame(); }
Shinya Kitaoka 473e70
  void redo() const override { setKeyFrame(); }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  void setKeyFrame() const {
Shinya Kitaoka 120a6e
    TPalette *palette = m_paletteHandle->getPalette();
Shinya Kitaoka 120a6e
    if (palette->isKeyframe(m_styleId, m_frame))
Shinya Kitaoka 120a6e
      palette->clearKeyframe(m_styleId, m_frame);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      palette->setKeyframe(m_styleId, m_frame);
Shinya Kitaoka 120a6e
    m_paletteHandle->notifyPaletteChanged();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// PaletteKeyframeNavigator
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool PaletteKeyframeNavigator::hasNext() const {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return false;
Shinya Kitaoka 120a6e
  int styleId = getStyleIndex();
Shinya Kitaoka 120a6e
  int frame   = getCurrentFrame();
Shinya Kitaoka 120a6e
  int n       = palette->getKeyframeCount(styleId);
Shinya Kitaoka 120a6e
  for (int i = n - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
    int f = palette->getKeyframe(styleId, i);
Shinya Kitaoka 120a6e
    if (f > frame)
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (f <= frame)
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool PaletteKeyframeNavigator::hasPrev() const {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return false;
Shinya Kitaoka 120a6e
  int styleId = getStyleIndex();
Shinya Kitaoka 120a6e
  int frame   = getCurrentFrame();
Shinya Kitaoka 120a6e
  int n       = palette->getKeyframeCount(styleId);
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) {
Shinya Kitaoka 120a6e
    int f = palette->getKeyframe(styleId, i);
Shinya Kitaoka 120a6e
    if (f < frame)
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (f >= frame)
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool PaletteKeyframeNavigator::hasKeyframes() const {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return false;
Shinya Kitaoka 120a6e
  return palette->getKeyframeCount(getStyleIndex()) > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool PaletteKeyframeNavigator::isKeyframe() const {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return false;
Shinya Kitaoka 120a6e
  int frame = getCurrentFrame();
Shinya Kitaoka 120a6e
  return palette->isKeyframe(getStyleIndex(), frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteKeyframeNavigator::toggle() {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int styleId = getStyleIndex(), frame = getCurrentFrame();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 2a7129
  std::unique_ptr<undopalettesetkeyframe> undo(</undopalettesetkeyframe>
Shinya Kitaoka 120a6e
      new UndoPaletteSetKeyFrame(styleId, frame, m_paletteHandle));
Shinya Kitaoka 120a6e
  undo->redo();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo.release());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteKeyframeNavigator::goNext() {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return;
Shinya Kitaoka 120a6e
  int styleId = getStyleIndex();
Shinya Kitaoka 120a6e
  int frame   = getCurrentFrame();
Shinya Kitaoka 120a6e
  int n       = palette->getKeyframeCount(styleId);
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++) {
Shinya Kitaoka 120a6e
    int f = palette->getKeyframe(styleId, i);
Shinya Kitaoka 120a6e
    if (f > frame) {
Shinya Kitaoka 120a6e
      setCurrentFrame(f);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteKeyframeNavigator::goPrev() {
Shinya Kitaoka 120a6e
  TPalette *palette = getPalette();
Shinya Kitaoka 120a6e
  if (!palette) return;
Shinya Kitaoka 120a6e
  int styleId = getStyleIndex();
Shinya Kitaoka 120a6e
  int frame   = getCurrentFrame();
Shinya Kitaoka 120a6e
  int n       = palette->getKeyframeCount(styleId);
Shinya Kitaoka 120a6e
  for (int i = n - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
    int f = palette->getKeyframe(styleId, i);
Shinya Kitaoka 120a6e
    if (f < frame) {
Shinya Kitaoka 120a6e
      setCurrentFrame(f);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteKeyframeNavigator::showEvent(QShowEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_paletteHandle) return;
Shinya Kitaoka 120a6e
  connect(m_paletteHandle, SIGNAL(paletteSwitched()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  connect(m_paletteHandle, SIGNAL(paletteChanged()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  connect(m_paletteHandle, SIGNAL(colorStyleSwitched()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  KeyframeNavigator::showEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PaletteKeyframeNavigator::hideEvent(QHideEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_paletteHandle) return;
Shinya Kitaoka 120a6e
  disconnect(m_paletteHandle);
Shinya Kitaoka 120a6e
  KeyframeNavigator::hideEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//! Se non c'e' un keyframe successivo ritorna frame
Shinya Kitaoka 120a6e
int getNextKeyframe(TFxP fx, int frame) {
Shinya Kitaoka 120a6e
  if (!fx) return frame;
Shinya Kitaoka 120a6e
  int targetFrame = frame;
Shinya Kitaoka 120a6e
  for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    int j         = param->getNextKeyframe(frame);
Shinya Kitaoka 120a6e
    if (j < 0) continue;
Shinya Kitaoka 120a6e
    int f = (int)param->keyframeIndexToFrame(j);
Shinya Kitaoka 120a6e
    if (targetFrame == frame || f < targetFrame) targetFrame = f;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return targetFrame;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//! Se non c'e' un keyframe precedente ritorna frame
Shinya Kitaoka 120a6e
int getPrevKeyframe(TFxP fx, int frame) {
Shinya Kitaoka 120a6e
  if (!fx) return frame;
Shinya Kitaoka 120a6e
  int targetFrame = frame;
Shinya Kitaoka 120a6e
  for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    int j         = param->getPrevKeyframe(frame);
Shinya Kitaoka 120a6e
    if (j < 0) continue;
Shinya Kitaoka 120a6e
    int f = (int)param->keyframeIndexToFrame(j);
Shinya Kitaoka 120a6e
    if (targetFrame == frame || f > targetFrame) targetFrame = f;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return targetFrame;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void setKeyframe(TFxP fx, int frame, bool on) {
Shinya Kitaoka 120a6e
  if (fx)
Shinya Kitaoka 120a6e
    for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
      TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
      if (TDoubleParamP dp = param) {
Shinya Kitaoka 120a6e
        if (on)
Shinya Kitaoka 120a6e
          dp->setValue(frame, dp->getValue(frame));
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          dp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // anonymous namespace
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// FxKeyframeNavigator
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxKeyframeNavigator::hasNext() const {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx)
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return getNextKeyframe(fx, getCurrentFrame()) > getCurrentFrame();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool FxKeyframeNavigator::hasPrev() const {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx)
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return getPrevKeyframe(fx, getCurrentFrame()) < getCurrentFrame();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool FxKeyframeNavigator::hasKeyframes() const {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return false;
Shinya Kitaoka 120a6e
  for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    if (param->hasKeyframes()) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool FxKeyframeNavigator::isKeyframe() const {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return false;
Shinya Kitaoka 120a6e
  for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    if (param->isKeyframe(getCurrentFrame())) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool FxKeyframeNavigator::isFullKeyframe() const {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return false;
Shinya Kitaoka 120a6e
  int keyFrameCount        = 0;
Shinya Kitaoka 120a6e
  int animatableParamCount = 0;
Shinya Kitaoka 120a6e
  for (int i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    if (param->isAnimatable()) {
Shinya Kitaoka 120a6e
      animatableParamCount++;
Shinya Kitaoka 120a6e
      if (param->isKeyframe(getCurrentFrame())) keyFrameCount++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return animatableParamCount > 0 && keyFrameCount == animatableParamCount;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FxKeyframeNavigator::toggle() {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return;
Shinya Kitaoka 120a6e
  int i, paramCount = fx->getParams()->getParamCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // determino in quale caso ci troviamo:
Shinya Kitaoka 120a6e
  // il frame corrente non e' keyframe di nessun parametro (isKeyframe=false),
Shinya Kitaoka 120a6e
  // di qualche parametro o di tutti i parametri (isFullKeyframe=true)
Shinya Kitaoka 120a6e
  bool isFullKeyframe = true;
Shinya Kitaoka 120a6e
  bool isKeyframe     = false;
Shinya Kitaoka 120a6e
  int frame           = getCurrentFrame();
Shinya Kitaoka 120a6e
  for (i = 0; i < paramCount; i++) {
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    if (!param->isAnimatable()) continue;
Shinya Kitaoka 120a6e
    if (param->isKeyframe(frame))
Shinya Kitaoka 120a6e
      isKeyframe = true;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      isFullKeyframe = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!isKeyframe) isFullKeyframe = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // modifico lo stato: nokeyframe->full, full->no, partial->full
Rozhuk Ivan 823a31
  bool on = (!isKeyframe || (isKeyframe && !isFullKeyframe));
Shinya Kitaoka 120a6e
  for (i = 0; i < fx->getParams()->getParamCount();
Shinya Kitaoka 120a6e
       i++) {  // TODO. spostare questo codice in TParam
Shinya Kitaoka 120a6e
    TParamP param = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
    if (TDoubleParamP dp = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        dp->setValue(frame, dp->getValue(frame));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        dp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    } else if (TRangeParamP rp = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        rp->setValue(frame, rp->getValue(frame));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        rp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    } else if (TPointParamP pp = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        pp->setValue(frame, pp->getValue(frame));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        pp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    } else if (TPixelParamP pip = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        pip->setValue(frame, pip->getValue(frame));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        pip->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    } else if (TSpectrumParamP sp = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        sp->setValue(frame, sp->getValue(frame), false);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        sp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    } else if (TToneCurveParamP tcp = param) {
Shinya Kitaoka 120a6e
      if (on)
Shinya Kitaoka 120a6e
        tcp->setValue(frame, tcp->getValue(frame), false);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        tcp->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_fxHandle->notifyFxChanged();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FxKeyframeNavigator::goNext() {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return;
Shinya Kitaoka 120a6e
  int frame = getNextKeyframe(fx, getCurrentFrame());
Shinya Kitaoka 120a6e
  if (frame > getCurrentFrame()) {
Shinya Kitaoka 120a6e
    setCurrentFrame(frame);
Shinya Kitaoka 120a6e
    //		m_fxHandle->notifyFxChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FxKeyframeNavigator::goPrev() {
Shinya Kitaoka 120a6e
  TFx *fx = getFx();
Shinya Kitaoka 120a6e
  if (!fx) return;
Shinya Kitaoka 120a6e
  int frame = getPrevKeyframe(fx, getCurrentFrame());
Shinya Kitaoka 120a6e
  if (frame < getCurrentFrame()) {
Shinya Kitaoka 120a6e
    setCurrentFrame(frame);
Shinya Kitaoka 120a6e
    //		m_fxHandle->notifyFxChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FxKeyframeNavigator::showEvent(QShowEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_fxHandle) return;
Shinya Kitaoka 120a6e
  connect(m_fxHandle, SIGNAL(fxSwitched()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  connect(m_fxHandle, SIGNAL(fxChanged()), this, SLOT(update()));
Shinya Kitaoka 120a6e
  KeyframeNavigator::showEvent(e);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FxKeyframeNavigator::hideEvent(QHideEvent *e) {
Shinya Kitaoka 120a6e
  if (!m_fxHandle) return;
Shinya Kitaoka 120a6e
  disconnect(m_fxHandle);
Shinya Kitaoka 120a6e
  KeyframeNavigator::hideEvent(e);
Toshihiro Shimizu 890ddd
}