Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/functionsegmentviewer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/intfield.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/filefield.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/doublefield.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/expressionfield.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/functionsheet.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/functionpanel.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/doubleparamcmd.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheetexpr.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tdoubleparam.h"
Toshihiro Shimizu 890ddd
#include "texpression.h"
Toshihiro Shimizu 890ddd
#include "tunit.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qgridlayout></qgridlayout>
Toshihiro Shimizu 890ddd
#include <qlabel></qlabel>
Toshihiro Shimizu 890ddd
#include <qstackedwidget></qstackedwidget>
Toshihiro Shimizu 890ddd
#include <qgroupbox></qgroupbox>
Toshihiro Shimizu 890ddd
#include <qcombobox></qcombobox>
Toshihiro Shimizu 890ddd
#include <qpushbutton></qpushbutton>
Toshihiro Shimizu 890ddd
#include <qintvalidator></qintvalidator>
Toshihiro Shimizu 890ddd
#include <qtextedit></qtextedit>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace DVGui;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton ccd505
static LineEdit *createField() {
Shinya Kitaoka 120a6e
  LineEdit *field = new LineEdit();
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
field->setMaximumWidth(100);
Shinya Kitaoka 120a6e
field->setFixedHeight(100);
Shinya Kitaoka 120a6e
field->setMinimumHeight(100);
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  return field;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSegmentPage::FunctionSegmentPage(FunctionSegmentViewer *parent)
Shinya Kitaoka 120a6e
    : QWidget(parent), m_viewer(parent) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionSegmentPage::~FunctionSegmentPage() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FunctionEmptySegmentPage final : public FunctionSegmentPage {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FunctionEmptySegmentPage(FunctionSegmentViewer *parent = 0)
Shinya Kitaoka 120a6e
      : FunctionSegmentPage(parent) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void refresh() override {}
Shinya Kitaoka 473e70
  void apply() override {}
Shinya Kitaoka 473e70
  void init(int segmentLength) override {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SpeedInOutSegmentPage::SpeedInOutSegmentPage(FunctionSegmentViewer *parent)
Shinya Kitaoka 120a6e
    : FunctionSegmentPage(parent) {
Shinya Kitaoka 120a6e
  m_speed0xFld = new LineEdit("0");
Shinya Kitaoka 120a6e
  m_speed0yFld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
  m_speed1xFld = new LineEdit("0");
Shinya Kitaoka 120a6e
  m_speed1yFld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_firstSpeedFld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
  m_lastSpeedFld  = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //----layout
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QGridLayout *mainLayout = new QGridLayout();
Shinya Kitaoka 120a6e
  mainLayout->setHorizontalSpacing(5);
Shinya Kitaoka 120a6e
  mainLayout->setVerticalSpacing(5);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(2);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("First Speed:")), 0, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_firstSpeedFld, 0, 1, 1, 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Handle:")), 1, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_speed0yFld, 1, 1);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("/")), 1, 2);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_speed0xFld, 1, 3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Last Speed:")), 2, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_lastSpeedFld, 2, 1, 1, 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Handle:")), 3, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_speed1yFld, 3, 1);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("/")), 3, 2);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_speed1xFld, 3, 3);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(0, 0);
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(1, 1);
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(2, 0);
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(3, 1);
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret = connect(m_speed0xFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                     SLOT(onFirstHandleXChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_speed0yFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                       SLOT(onFirstHandleYChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_firstSpeedFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                       SLOT(onFirstSpeedChanged()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(m_speed1xFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                       SLOT(onLastHandleXChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_speed1yFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                       SLOT(onLastHandleYChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_lastSpeedFld, SIGNAL(editingFinished()), this,
Shinya Kitaoka 120a6e
                       SLOT(onLastSpeedChanged()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(ret);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onFirstHandleXChanged() {
Shinya Kitaoka 120a6e
  double x = m_speed0xFld->text().toDouble();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 前のSegmentが存在して、Linkしていて、SpeedIn/Outでない場合、
Shinya Kitaoka 120a6e
            Speedを保持してハンドルの長さを変える。---*/
Shinya Kitaoka 120a6e
  int segmentIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (segmentIndex > 0) /*--- 前のSegmentが存在している条件 ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TDoubleKeyframe kf = getCurve()->getKeyframe(segmentIndex);
Shinya Kitaoka 120a6e
    /*--- Linkしていて、SpeedIn/Outでない場合の条件 ---*/
Shinya Kitaoka 120a6e
    if (kf.m_linkedHandles && kf.m_prevType != TDoubleKeyframe::SpeedInOut) {
Shinya Kitaoka 120a6e
      double speed = m_firstSpeedFld->getValue();
Shinya Kitaoka 120a6e
      m_speed0yFld->setValue(x * speed);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 条件から外れる場合 ---*/
Shinya Kitaoka 120a6e
  double y = m_speed0yFld->getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x != 0.0)
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setValue(y / x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setText(tr("---"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onFirstHandleYChanged() {
Shinya Kitaoka 120a6e
  double y = m_speed0yFld->getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 前のSegmentが存在して、Linkしていて、SpeedIn/Outでない場合、
Shinya Kitaoka 120a6e
  Speedを保持してハンドルの長さを変える。---*/
Shinya Kitaoka 120a6e
  int segmentIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (segmentIndex > 0) /*--- 前のSegmentが存在している条件 ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TDoubleKeyframe kf = getCurve()->getKeyframe(segmentIndex);
Shinya Kitaoka 120a6e
    /*--- Linkしていて、SpeedIn/Outでない場合の条件 ---*/
Shinya Kitaoka 120a6e
    if (kf.m_linkedHandles && kf.m_prevType != TDoubleKeyframe::SpeedInOut) {
Shinya Kitaoka 120a6e
      double speed = m_firstSpeedFld->getValue();
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(speed, 0.0, 0.001))
Shinya Kitaoka 120a6e
        m_speed0xFld->setText(QString::number(y / speed, 'f', 1));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_speed0xFld->setText(QString::number(0, 'f', 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 条件から外れる場合 ---*/
Shinya Kitaoka 120a6e
  double x = m_speed0xFld->text().toDouble();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (x != 0.0)
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setValue(y / x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setText(tr("---"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onFirstSpeedChanged() {
Shinya Kitaoka 120a6e
  /*--- Speedを変えた場合は、Valueを変える。 ---*/
Shinya Kitaoka 120a6e
  double speed = m_firstSpeedFld->getValue();
Shinya Kitaoka 120a6e
  double x     = m_speed0xFld->text().toDouble();
Shinya Kitaoka 120a6e
  m_speed0yFld->setValue(speed * x);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onLastHandleXChanged() {
Shinya Kitaoka 120a6e
  double x = m_speed1xFld->text().toDouble();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 後のSegmentが存在して、Linkしていて、SpeedIn/Outでない場合、
Shinya Kitaoka 120a6e
           Speedを保持してハンドルの長さを変える。 ---*/
Shinya Kitaoka 120a6e
  int segmentIndex    = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (curve && curve->getKeyframeCount() >= 3 &&
Shinya Kitaoka 120a6e
      segmentIndex < curve->getKeyframeCount() -
Shinya Kitaoka 120a6e
                         2) /*--- 後のSegmentが存在している条件 ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TDoubleKeyframe kf = getCurve()->getKeyframe(segmentIndex + 1);
Shinya Kitaoka 120a6e
    /*--- Linkしていて、SpeedIn/Outでない場合の条件 ---*/
Shinya Kitaoka 120a6e
    if (kf.m_linkedHandles && kf.m_type != TDoubleKeyframe::SpeedInOut) {
Shinya Kitaoka 120a6e
      double speed = m_lastSpeedFld->getValue();
Shinya Kitaoka 120a6e
      m_speed1yFld->setValue(x * speed);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 条件から外れる場合 ---*/
Shinya Kitaoka 120a6e
  double y = m_speed1yFld->getValue();
Shinya Kitaoka 120a6e
  if (x != 0.0)
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setValue(y / x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setText(tr("---"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onLastHandleYChanged() {
Shinya Kitaoka 120a6e
  double y = m_speed1yFld->getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 後のSegmentが存在して、Linkしていて、SpeedIn/Outでない場合、
Shinya Kitaoka 120a6e
  Speedを保持してハンドルの長さを変える。 ---*/
Shinya Kitaoka 120a6e
  int segmentIndex    = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (curve && curve->getKeyframeCount() >= 3 &&
Shinya Kitaoka 120a6e
      segmentIndex < curve->getKeyframeCount() -
Shinya Kitaoka 120a6e
                         2) /*--- 後のSegmentが存在している条件 ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TDoubleKeyframe kf = getCurve()->getKeyframe(segmentIndex + 1);
Shinya Kitaoka 120a6e
    /*--- Linkしていて、SpeedIn/Outでない場合の条件 ---*/
Shinya Kitaoka 120a6e
    if (kf.m_linkedHandles && kf.m_type != TDoubleKeyframe::SpeedInOut) {
Shinya Kitaoka 120a6e
      double speed = m_lastSpeedFld->getValue();
Shinya Kitaoka 120a6e
      std::cout << "speed: " << speed << std::endl;
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(speed, 0.0, 0.001))
Shinya Kitaoka 120a6e
        m_speed1xFld->setText(QString::number(y / speed, 'f', 1));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_speed1xFld->setText(QString::number(0, 'f', 1));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 条件から外れる場合 ---*/
Shinya Kitaoka 120a6e
  double x = m_speed1xFld->text().toDouble();
Shinya Kitaoka 120a6e
  if (x != 0.0)
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setValue(y / x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setText(tr("---"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::onLastSpeedChanged() {
Shinya Kitaoka 120a6e
  /*--- Speedを変えた場合は、Valueを変える。 ---*/
Shinya Kitaoka 120a6e
  double speed = m_lastSpeedFld->getValue();
Shinya Kitaoka 120a6e
  double x     = m_speed1xFld->text().toDouble();
Shinya Kitaoka 120a6e
  m_speed1yFld->setValue(speed * x);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::refresh() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  int kIndex          = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (!curve || kIndex < 0 || kIndex + 1 >= curve->getKeyframeCount()) return;
Shinya Kitaoka 120a6e
  if (curve->getKeyframe(kIndex).m_type != TDoubleKeyframe::SpeedInOut) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string measureName = curve->getMeasureName();
Shinya Kitaoka 120a6e
  if (measureName == "zdepth")
Shinya Kitaoka 120a6e
    measureName = "zdepth.handle";
Shinya Kitaoka 120a6e
  else if (measureName == "zdepth.cam")
Shinya Kitaoka 120a6e
    measureName = "zdepth.cam.handle";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD speedOut = curve->getSpeedOut(kIndex);
Shinya Kitaoka 120a6e
  m_speed0xFld->setText(QString::number(speedOut.x, 'f', 1));
Shinya Kitaoka 120a6e
  m_speed0yFld->setMeasure(measureName);
Shinya Kitaoka 120a6e
  m_speed0yFld->setValue(speedOut.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_firstSpeedFld->setMeasure(measureName);
Shinya Kitaoka 120a6e
  if (speedOut.x != 0.0)
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setValue(speedOut.y / speedOut.x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setText(tr("---"));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD speedIn = curve->getSpeedIn(kIndex + 1);
Shinya Kitaoka 120a6e
  m_speed1xFld->setText(QString::number(speedIn.x, 'f', 1));
Shinya Kitaoka 120a6e
  m_speed1yFld->setMeasure(measureName);
Shinya Kitaoka 120a6e
  m_speed1yFld->setValue(speedIn.y);
Shinya Kitaoka 120a6e
  m_lastSpeedFld->setMeasure(measureName);
Shinya Kitaoka 120a6e
  if (speedIn.x != 0.0)
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setValue(speedIn.y / speedIn.x);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setText(tr("---"));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- キーフレームがリンク、かつ隣がSpeedIn/Outでないとき、
Shinya Kitaoka 120a6e
          Speed入力BoxをDisableする。それ以外の場合はEnableする ---*/
Shinya Kitaoka 120a6e
  // PrevKey
Shinya Kitaoka 120a6e
  if (kIndex > 0 && curve->getKeyframe(kIndex).m_linkedHandles &&
Shinya Kitaoka 120a6e
      curve->getKeyframe(kIndex).m_prevType != TDoubleKeyframe::SpeedInOut)
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setEnabled(false);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_firstSpeedFld->setEnabled(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NextKey
Shinya Kitaoka 120a6e
  if (curve->getKeyframeCount() >= 3 &&
Shinya Kitaoka 120a6e
      kIndex < curve->getKeyframeCount() - 2 &&
Shinya Kitaoka 120a6e
      curve->getKeyframe(kIndex + 1).m_linkedHandles &&
Shinya Kitaoka 120a6e
      curve->getKeyframe(kIndex + 1).m_type != TDoubleKeyframe::SpeedInOut)
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setEnabled(false);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_lastSpeedFld->setEnabled(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::init(int segmentLength) {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_speed0xFld->setText(QString::number((double)segmentLength / 3.0));
Shinya Kitaoka 120a6e
  m_speed0yFld->setMeasure(curve->getMeasureName());
Shinya Kitaoka 120a6e
  m_speed0yFld->setValue(0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_firstSpeedFld->setMeasure(curve->getMeasureName());
Shinya Kitaoka 120a6e
  m_firstSpeedFld->setValue(0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_speed1xFld->setText(QString::number(-(double)segmentLength / 3.0));
Shinya Kitaoka 120a6e
  m_speed1yFld->setMeasure(curve->getMeasureName());
Shinya Kitaoka 120a6e
  m_speed1yFld->setValue(0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_lastSpeedFld->setMeasure(curve->getMeasureName());
Shinya Kitaoka 120a6e
  m_lastSpeedFld->setValue(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SpeedInOutSegmentPage::getGuiValues(TPointD &speedIn, TPointD &speedOut) {
Shinya Kitaoka 120a6e
  speedOut.x = m_speed0xFld->text().toDouble();
Shinya Kitaoka 120a6e
  speedOut.y = m_speed0yFld->getValue();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  speedIn.x = m_speed1xFld->text().toDouble();
Shinya Kitaoka 120a6e
  speedIn.y = m_speed1yFld->getValue();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
EaseInOutSegmentPage::EaseInOutSegmentPage(bool isPercentage,
Shinya Kitaoka 120a6e
                                           FunctionSegmentViewer *parent)
Shinya Kitaoka 120a6e
    : FunctionSegmentPage(parent)
Shinya Kitaoka 120a6e
    , m_fieldScale(isPercentage ? 100.0 : 1.0)
Shinya Kitaoka 120a6e
    , m_isPercentage(isPercentage) {
Shinya Kitaoka 120a6e
  std::string measureName = isPercentage ? "percentage" : "";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_ease0Fld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
  m_ease0Fld->setMeasure(measureName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_ease1Fld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
  m_ease1Fld->setMeasure(measureName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_ease0Fld->setText("0");
Shinya Kitaoka 120a6e
  m_ease1Fld->setText("0");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //----layout
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QGridLayout *mainLayout = new QGridLayout();
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(5);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(2);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Ease In:")), 0, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_ease0Fld, 0, 1);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Ease Out:")), 1, 0,
Shinya Kitaoka 120a6e
                          Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_ease1Fld, 1, 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(0, 0);
Shinya Kitaoka 120a6e
  mainLayout->setColumnStretch(1, 1);
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EaseInOutSegmentPage::refresh() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) return;
Shinya Kitaoka 120a6e
  TDoubleKeyframe kf0 = curve->getKeyframeAt(getR0());
Shinya Kitaoka 120a6e
  TDoubleKeyframe kf1 = curve->getKeyframeAt(getR1());
Shinya Kitaoka 120a6e
  m_ease0Fld->setValue(kf0.m_speedOut.x / m_fieldScale);
Shinya Kitaoka 120a6e
  m_ease1Fld->setValue(-kf1.m_speedIn.x / m_fieldScale);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EaseInOutSegmentPage::onEase0Changed() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  int kIndex          = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (!curve || kIndex < 0) return;
Shinya Kitaoka 120a6e
  KeyframeSetter setter(curve, kIndex);
Shinya Kitaoka 120a6e
  setter.setEaseOut(m_ease0Fld->getValue() * m_fieldScale);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EaseInOutSegmentPage::onEase1Changed() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  int kIndex          = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (!curve || kIndex < 0) return;
Shinya Kitaoka 120a6e
  KeyframeSetter setter(curve, kIndex + 1);
Shinya Kitaoka 120a6e
  setter.setEaseIn(-m_ease1Fld->getValue() * m_fieldScale);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EaseInOutSegmentPage::init(int segmentLength) {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) return;
Shinya Kitaoka 120a6e
  int kIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*---- 既にあるSegment上でTypeを切り替えたとき ----*/
Shinya Kitaoka 120a6e
  if (0 <= kIndex && kIndex < curve->getKeyframeCount() - 1) {
Shinya Kitaoka 120a6e
    TDoubleKeyframe keyFrame     = curve->getKeyframe(kIndex);
Shinya Kitaoka 120a6e
    TDoubleKeyframe nextKeyFrame = curve->getKeyframe(kIndex + 1);
Shinya Kitaoka 120a6e
    double ease0 = 0, ease1 = 0;
Shinya Kitaoka 120a6e
    /*--- EaseInOut(Frame)からEaseIO(%)に切り替えたとき ---*/
Shinya Kitaoka 120a6e
    if (keyFrame.m_type == TDoubleKeyframe::EaseInOut && m_isPercentage) {
Shinya Kitaoka 120a6e
      // absolute -> percentage
Shinya Kitaoka 120a6e
      ease0 = keyFrame.m_speedOut.x / (double)segmentLength;
Shinya Kitaoka 120a6e
      ease1 = -nextKeyFrame.m_speedIn.x / (double)segmentLength;
Shinya Kitaoka 120a6e
      ease0 = tcrop(ease0, 0.0, 1.0);
Shinya Kitaoka 120a6e
      ease1 = tcrop(ease1, 0.0, 1.0 - ease0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    //*--- EaseIO(%)からEaseInOut(Frame)に切り替えたとき ---*/
Shinya Kitaoka 120a6e
    else if (keyFrame.m_type == TDoubleKeyframe::EaseInOutPercentage &&
Shinya Kitaoka 120a6e
             !m_isPercentage) {
Shinya Kitaoka 120a6e
      // percentage -> absolute
Shinya Kitaoka 120a6e
      ease0 = keyFrame.m_speedOut.x * 0.01 * (double)segmentLength;
Shinya Kitaoka 120a6e
      ease1 = -nextKeyFrame.m_speedIn.x * 0.01 * (double)segmentLength;
Shinya Kitaoka 120a6e
      ease0 = tcrop(ease0, 0.0, (double)segmentLength);
Shinya Kitaoka 120a6e
      ease1 = tcrop(ease1, 0.0, (double)segmentLength - ease0);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      ease1 = ease0 = ((m_isPercentage) ? 1.0 : (double)segmentLength) / 3.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_isPercentage) {
Shinya Kitaoka 120a6e
      ease0 = floor(ease0 + 0.5);
Shinya Kitaoka 120a6e
      ease1 = floor(ease1 + 0.5);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_ease0Fld->setValue(ease0);
Shinya Kitaoka 120a6e
    m_ease1Fld->setValue(ease1);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    double value = ((m_isPercentage) ? 1.0 : (double)segmentLength) / 3.0;
Shinya Kitaoka 120a6e
    if (!m_isPercentage) value = floor(value + 0.5);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_ease0Fld->setValue(value);
Shinya Kitaoka 120a6e
    m_ease1Fld->setValue(value);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EaseInOutSegmentPage::getGuiValues(TPointD &easeIn, TPointD &easeOut) {
Shinya Kitaoka 120a6e
  easeOut.x = m_ease0Fld->getValue() * m_fieldScale;
Shinya Kitaoka 120a6e
  easeOut.y = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  easeIn.x = -m_ease1Fld->getValue() * m_fieldScale;
Shinya Kitaoka 120a6e
  easeIn.y = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionExpressionSegmentPage::FunctionExpressionSegmentPage(
Shinya Kitaoka 120a6e
    FunctionSegmentViewer *parent)
Shinya Kitaoka 120a6e
    : FunctionSegmentPage(parent) {
Shinya Kitaoka 120a6e
  m_expressionFld = new DVGui::ExpressionField();
Shinya Kitaoka 120a6e
  m_expressionFld->setFixedHeight(21);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QLabel *unitLabel = new QLabel(tr("Unit:"));
Shinya Kitaoka 120a6e
  unitLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_unitFld = createField();
Shinya Kitaoka 120a6e
  m_unitFld->setFixedWidth(40);
Shinya Kitaoka 120a6e
  m_unitFld->setText("inch");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---- layout
Shinya Kitaoka 120a6e
  QVBoxLayout *mainLayout = new QVBoxLayout();
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(2);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(2);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    mainLayout->addSpacing(3);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Expression:")));
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_expressionFld);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addSpacing(3);
Shinya Kitaoka 120a6e
    QHBoxLayout *unitLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      unitLay->addWidget(unitLabel);
Shinya Kitaoka 120a6e
      unitLay->addWidget(m_unitFld);
Shinya Kitaoka 120a6e
      unitLay->addStretch();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    mainLayout->addLayout(unitLay);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionExpressionSegmentPage::refresh() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) {
Shinya Kitaoka 120a6e
    m_expressionFld->setGrammar(0);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDoubleKeyframe kf0        = curve->getKeyframeAt(getR0());
Shinya Kitaoka 120a6e
  std::string expression     = kf0.m_expressionText;
Shinya Kitaoka 120a6e
  bool oldBlockSignalsStatus = m_expressionFld->blockSignals(true);
Shinya Kitaoka 120a6e
  m_expressionFld->setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  m_expressionFld->setExpression(expression);
Shinya Kitaoka 120a6e
  m_expressionFld->blockSignals(oldBlockSignalsStatus);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::wstring unitName = ::to_wstring(kf0.m_unitName);
Shinya Kitaoka 120a6e
  if (unitName == L"" && curve->getMeasure())
Shinya Kitaoka 120a6e
    unitName = curve->getMeasure()->getCurrentUnit()->getDefaultExtension();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  oldBlockSignalsStatus = m_unitFld->blockSignals(true);
Shinya Kitaoka 120a6e
  m_unitFld->setText(QString::fromStdWString(unitName));
Shinya Kitaoka 120a6e
  m_unitFld->blockSignals(oldBlockSignalsStatus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionExpressionSegmentPage::init(int segmentLength) {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) {
Shinya Kitaoka 120a6e
    m_expressionFld->setGrammar(0);
Shinya Kitaoka 120a6e
    m_expressionFld->setEnabled(false);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_expressionFld->setEnabled(true);
Shinya Kitaoka 120a6e
  m_expressionFld->setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int kIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- すでにあるカーブをExpressionに切り替えた場合 ---*/
Shinya Kitaoka 120a6e
  if (kIndex >= 0) {
Shinya Kitaoka 120a6e
    TDoubleKeyframe keyFrame      = curve->getKeyframe(kIndex);
Shinya Kitaoka 120a6e
    double value                  = curve->getValue(keyFrame.m_frame);
Shinya Kitaoka 120a6e
    const TUnit *unit             = 0;
Shinya Kitaoka 120a6e
    if (curve->getMeasure()) unit = curve->getMeasure()->getCurrentUnit();
Shinya Kitaoka 120a6e
    if (unit) value               = unit->convertTo(value);
Shinya Kitaoka 120a6e
    m_expressionFld->setExpression(QString::number(value).toStdString());
Shinya Kitaoka 120a6e
    /*--- unitがある場合だけUnitを表示 ---*/
Shinya Kitaoka 120a6e
    if (unit)
Shinya Kitaoka 120a6e
      m_unitFld->setText(QString::fromStdWString(unit->getDefaultExtension()));
Toshihiro Shimizu 890ddd
    else
Shinya Kitaoka 120a6e
      m_unitFld->setText("");
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_expressionFld->setExpression("0");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::wstring unitName = L"inch";
Shinya Kitaoka 120a6e
    if (curve->getMeasure())
Shinya Kitaoka 120a6e
      unitName = curve->getMeasure()->getCurrentUnit()->getDefaultExtension();
Shinya Kitaoka 120a6e
    m_unitFld->setText(QString::fromStdWString(unitName));
Toshihiro Shimizu 890ddd
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void FunctionExpressionSegmentPage::apply() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int kIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (kIndex < 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string expressionText = m_expressionFld->getExpression();
Shinya Kitaoka 120a6e
  TExpression expr;
Shinya Kitaoka 120a6e
  expr.setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  expr.setText(expressionText);
Shinya Kitaoka 120a6e
  if (dependsOn(expr, curve)) {
Shinya Kitaoka 120a6e
    DVGui::warning(
Shinya Kitaoka 120a6e
        tr("There is a circular reference in the definition of the "
Shinya Kitaoka 120a6e
           "interpolation."));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string unitName = m_unitFld->text().toStdString();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  KeyframeSetter setter(curve, kIndex);
Shinya Kitaoka 120a6e
  setter.setExpression(m_expressionFld->getExpression());
Shinya Kitaoka 120a6e
  setter.setUnitName(unitName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TDoubleKeyframe kf0 = curve->getKeyframeAt(getR0());
Shinya Kitaoka 120a6e
kf0.m_expressionText = m_expressionFld->getExpression();
Shinya Kitaoka 120a6e
kf0.m_unitName = m_unitFld->text().toStdString();
Shinya Kitaoka 120a6e
curve->setKeyframe(kf0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
wstring unitExtension = m_unitFld->text().toStdWString();
Shinya Kitaoka 120a6e
TMeasure *curveMeasure = curve->getMeasure();
Shinya Kitaoka 120a6e
if(curveMeasure)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
TUnit *unit = curveMeasure->getUnit(unitExtension);
Shinya Kitaoka 120a6e
if(unit)
Shinya Kitaoka 120a6e
curveMeasure->setCurrentUnit(unit);
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
unitExtension = curveMeasure->getCurrentUnit()->getDefaultExtension();
Shinya Kitaoka 120a6e
m_unitFld->setText(QString::fromStdWString(unitExtension));
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
else
Shinya Kitaoka 120a6e
m_unitFld->setText("");
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! return false if a circular reference is occured
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
bool FunctionExpressionSegmentPage::getGuiValues(std::string &expressionText,
Shinya Kitaoka 120a6e
                                                 std::string &unitName) {
Shinya Kitaoka 120a6e
  expressionText = m_expressionFld->getExpression();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // checking a circular reference
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  TExpression expr;
Shinya Kitaoka 120a6e
  expr.setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  expr.setText(expressionText);
Shinya Kitaoka 120a6e
  if (dependsOn(expr, curve)) {
Shinya Kitaoka 120a6e
    DVGui::warning(
Shinya Kitaoka 120a6e
        tr("There is a circular reference in the definition of the "
Shinya Kitaoka 120a6e
           "interpolation."));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unitName = m_unitFld->text().toStdString();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_expressionFld->hasFocus()) m_expressionFld->clearFocus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
shun-iwasawa e87e08
FileSegmentPage::FileSegmentPage(FunctionSegmentViewer *parent)
shun-iwasawa e87e08
    : FunctionSegmentPage(parent) {
shun-iwasawa 42cc64
  // Force decoding the path since the file interporation
shun-iwasawa 42cc64
  // currently accepts only absolute paths.
shun-iwasawa 42cc64
  m_fileFld = new DVGui::FileField(this, QString(), false, false, false);
shun-iwasawa e87e08
  m_fileFld->setFileMode(QFileDialog::ExistingFile);
shun-iwasawa e87e08
  QStringList filters;
shun-iwasawa e87e08
  filters.append("dat");
shun-iwasawa e87e08
  filters.append("txt");
shun-iwasawa e87e08
  m_fileFld->setFilters(filters);
Toshihiro Shimizu 890ddd
shun-iwasawa e87e08
  m_fieldIndexFld             = new LineEdit(this);
shun-iwasawa e87e08
  QIntValidator *intValidator = new QIntValidator(1, 100, this);
shun-iwasawa e87e08
  m_fieldIndexFld->setValidator(intValidator);
shun-iwasawa e87e08
shun-iwasawa e87e08
  m_measureFld = new LineEdit(this);
shun-iwasawa e87e08
  m_measureFld->setText("inch");
shun-iwasawa e87e08
shun-iwasawa e87e08
  //----layout
shun-iwasawa e87e08
  QVBoxLayout *mainLayout = new QVBoxLayout();
shun-iwasawa e87e08
  mainLayout->setSpacing(5);
shun-iwasawa e87e08
  mainLayout->setMargin(2);
shun-iwasawa e87e08
  {
shun-iwasawa e87e08
    mainLayout->addWidget(new QLabel(tr("File Path:")), 0);
shun-iwasawa e87e08
    mainLayout->addWidget(m_fileFld);
shun-iwasawa e87e08
shun-iwasawa e87e08
    QGridLayout *bottomLay = new QGridLayout();
shun-iwasawa e87e08
    bottomLay->setSpacing(5);
shun-iwasawa e87e08
    bottomLay->setMargin(0);
Shinya Kitaoka 120a6e
    {
shun-iwasawa e87e08
      bottomLay->addWidget(new QLabel(tr("Column:")), 0, 0,
shun-iwasawa e87e08
                           Qt::AlignRight | Qt::AlignVCenter);
shun-iwasawa e87e08
      bottomLay->addWidget(m_fieldIndexFld, 0, 1);
shun-iwasawa e87e08
      bottomLay->addWidget(new QLabel(tr("Unit:")), 1, 0,
shun-iwasawa e87e08
                           Qt::AlignRight | Qt::AlignVCenter);
shun-iwasawa e87e08
      bottomLay->addWidget(m_measureFld, 1, 1);
Shinya Kitaoka 120a6e
    }
shun-iwasawa e87e08
    bottomLay->setColumnStretch(0, 0);
shun-iwasawa e87e08
    bottomLay->setColumnStretch(1, 1);
shun-iwasawa e87e08
    mainLayout->addLayout(bottomLay);
Shinya Kitaoka 120a6e
  }
shun-iwasawa e87e08
  setLayout(mainLayout);
shun-iwasawa e87e08
}
shun-iwasawa e87e08
shun-iwasawa e87e08
void FileSegmentPage::refresh() {
shun-iwasawa e87e08
  TDoubleKeyframe kf;
shun-iwasawa e87e08
  TDoubleParam *curve = getCurve();
shun-iwasawa e87e08
  if (curve) kf       = curve->getKeyframeAt(getR0());
shun-iwasawa e87e08
  if (curve && kf.m_isKeyframe) {
shun-iwasawa e87e08
    TFilePath path;
shun-iwasawa e87e08
    int fieldIndex       = 0;
shun-iwasawa e87e08
    std::string unitName = "";
shun-iwasawa e87e08
    if (kf.m_type == TDoubleKeyframe::File) {
shun-iwasawa e87e08
      path                           = kf.m_fileParams.m_path;
shun-iwasawa e87e08
      fieldIndex                     = kf.m_fileParams.m_fieldIndex;
shun-iwasawa e87e08
      if (fieldIndex < 0) fieldIndex = 0;
shun-iwasawa e87e08
      unitName                       = kf.m_unitName;
shun-iwasawa e87e08
      if (unitName == "") {
shun-iwasawa e87e08
        TMeasure *measure = curve->getMeasure();
shun-iwasawa e87e08
        if (measure) {
shun-iwasawa e87e08
          const TUnit *unit  = measure->getCurrentUnit();
shun-iwasawa e87e08
          if (unit) unitName = ::to_string(unit->getDefaultExtension());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa e87e08
    m_fileFld->setPath(QString::fromStdWString(path.getWideString()));
shun-iwasawa e87e08
    m_fieldIndexFld->setText(QString::number(fieldIndex + 1));
shun-iwasawa e87e08
    m_measureFld->setText(QString::fromStdString(unitName));
Shinya Kitaoka 120a6e
  }
shun-iwasawa e87e08
}
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
void FileSegmentPage::init(int segmentLength) {
shun-iwasawa e87e08
  TDoubleParam *curve = getCurve();
shun-iwasawa e87e08
  if (!curve) return;
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  TMeasure *measure    = curve->getMeasure();
shun-iwasawa e87e08
  std::string unitName = "";
shun-iwasawa e87e08
  if (measure) {
shun-iwasawa e87e08
    const TUnit *unit  = measure->getCurrentUnit();
shun-iwasawa e87e08
    if (unit) unitName = ::to_string(unit->getDefaultExtension());
Shinya Kitaoka 120a6e
  }
shun-iwasawa e87e08
  m_measureFld->setText(QString::fromStdString(unitName));
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  m_fileFld->setPath("");
shun-iwasawa e87e08
  m_fieldIndexFld->setText("");
shun-iwasawa e87e08
}
shun-iwasawa e87e08
shun-iwasawa e87e08
void FileSegmentPage::apply() {
shun-iwasawa e87e08
  TDoubleParam *curve = getCurve();
shun-iwasawa e87e08
  if (!curve) return;
shun-iwasawa e87e08
  int kIndex = getViewer()->getSegmentIndex();
shun-iwasawa e87e08
  if (kIndex < 0) return;
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  QString stringPath = m_fileFld->getPath();
shun-iwasawa e87e08
  if (stringPath == "") return;
shun-iwasawa e87e08
  stringPath.replace("\\", "\\\\");
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  TDoubleKeyframe::FileParams fileParams;
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  fileParams.m_path       = TFilePath(stringPath.toStdWString());
shun-iwasawa e87e08
  fileParams.m_fieldIndex = qMax(0, m_fieldIndexFld->text().toInt() - 1);
shun-iwasawa e87e08
  std::string unitName    = m_measureFld->text().toStdString();
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  KeyframeSetter setter(curve, kIndex);
shun-iwasawa e87e08
  setter.setFile(fileParams);
shun-iwasawa e87e08
  setter.setUnitName(unitName);
shun-iwasawa e87e08
}
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
void FileSegmentPage::getGuiValues(TDoubleKeyframe::FileParams &fileParam,
shun-iwasawa e87e08
                                   std::string &unitName) {
shun-iwasawa e87e08
  QString stringPath = m_fileFld->getPath();
shun-iwasawa e87e08
  stringPath.replace("\\", "\\\\");
shun-iwasawa e87e08
  fileParam.m_path       = TFilePath(stringPath.toStdWString());
shun-iwasawa e87e08
  fileParam.m_fieldIndex = qMax(0, m_fieldIndexFld->text().toInt() - 1);
Shinya Kitaoka 120a6e
shun-iwasawa e87e08
  unitName = m_measureFld->text().toStdString();
shun-iwasawa e87e08
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SimilarShapeSegmentPage::SimilarShapeSegmentPage(FunctionSegmentViewer *parent)
Shinya Kitaoka 120a6e
    : FunctionSegmentPage(parent) {
Shinya Kitaoka 120a6e
  m_expressionFld = new DVGui::ExpressionField();
Shinya Kitaoka 120a6e
  m_offsetFld     = createField();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //----layout
Shinya Kitaoka 120a6e
  QVBoxLayout *mainLayout = new QVBoxLayout();
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(2);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(2);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    mainLayout->addSpacing(3);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(new QLabel(tr("Reference Curve:")));
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_expressionFld);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    mainLayout->addSpacing(3);
Shinya Kitaoka 120a6e
    QHBoxLayout *offLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      offLay->addWidget(new QLabel(tr("Frame Offset:")));
Shinya Kitaoka 120a6e
      offLay->addWidget(m_offsetFld);
Shinya Kitaoka 120a6e
      offLay->addStretch();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    mainLayout->addLayout(offLay);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SimilarShapeSegmentPage::refresh() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) {
Shinya Kitaoka 120a6e
    m_expressionFld->setGrammar(0);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDoubleKeyframe kf0        = curve->getKeyframeAt(getR0());
Shinya Kitaoka 120a6e
  std::string expression     = kf0.m_expressionText;
Shinya Kitaoka 120a6e
  bool oldBlockSignalsStatus = m_expressionFld->blockSignals(true);
Shinya Kitaoka 120a6e
  m_expressionFld->setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  m_expressionFld->setExpression(expression);
Shinya Kitaoka 120a6e
  m_expressionFld->blockSignals(oldBlockSignalsStatus);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_offsetFld->setText(QString::number(kf0.m_similarShapeOffset, 'f', 0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SimilarShapeSegmentPage::init(int segmentLength) {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) {
Shinya Kitaoka 120a6e
    m_expressionFld->setGrammar(0);
Shinya Kitaoka 120a6e
    m_expressionFld->setEnabled(false);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_expressionFld->setEnabled(true);
Shinya Kitaoka 120a6e
  TDoubleKeyframe kf0        = curve->getKeyframeAt(getR0());
Shinya Kitaoka 120a6e
  std::string expression     = kf0.m_expressionText;
Shinya Kitaoka 120a6e
  bool oldBlockSignalsStatus = m_expressionFld->blockSignals(true);
Shinya Kitaoka 120a6e
  m_expressionFld->setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  m_expressionFld->setExpression(expression);
Shinya Kitaoka 120a6e
  m_expressionFld->blockSignals(oldBlockSignalsStatus);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_offsetFld->setText(QString::number(kf0.m_similarShapeOffset, 'f', 0));
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void SimilarShapeSegmentPage::apply() {
Shinya Kitaoka 120a6e
  TDoubleParam *curve = getCurve();
Shinya Kitaoka 120a6e
  if (!curve) return;
Shinya Kitaoka 120a6e
  int kIndex = getViewer()->getSegmentIndex();
Shinya Kitaoka 120a6e
  if (kIndex < 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string expressionText = m_expressionFld->getExpression();
Shinya Kitaoka 120a6e
  TExpression expr;
Shinya Kitaoka 120a6e
  expr.setGrammar(curve->getGrammar());
Shinya Kitaoka 120a6e
  expr.setText(expressionText);
Shinya Kitaoka 120a6e
  if (!expr.isValid()) {
Shinya Kitaoka 120a6e
    DVGui::warning(
Shinya Kitaoka 120a6e
        tr("There is a syntax error in the definition of the interpolation."));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (dependsOn(expr, curve)) {
Shinya Kitaoka 120a6e
    DVGui::warning(
Shinya Kitaoka 120a6e
        tr("There is a circular reference in the definition of the "
Shinya Kitaoka 120a6e
           "interpolation."));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  KeyframeSetter setter(curve, kIndex);
Shinya Kitaoka 120a6e
  setter.setSimilarShape(m_expressionFld->getExpression(),
Shinya Kitaoka 120a6e
                         m_offsetFld->text().toDouble());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void SimilarShapeSegmentPage::getGuiValues(std::string &expressionText,
Shinya Kitaoka 120a6e
                                           double &similarShapeOffset) {
Shinya Kitaoka 120a6e
  expressionText     = m_expressionFld->getExpression();
Shinya Kitaoka 120a6e
  similarShapeOffset = m_offsetFld->text().toDouble();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionSegmentViewer::FunctionSegmentViewer(QWidget *parent,
Shinya Kitaoka 120a6e
                                             FunctionSheet *sheet,
Shinya Kitaoka 120a6e
                                             FunctionPanel *panel)
Shinya Kitaoka 120a6e
    : QFrame(parent)
Shinya Kitaoka 120a6e
    , m_curve(0)
Shinya Kitaoka 120a6e
    , m_r0(0)
Shinya Kitaoka 120a6e
    , m_r1(0)
Shinya Kitaoka 120a6e
    , m_sheet(sheet)
Shinya Kitaoka 120a6e
    , m_xshHandle(0)
Shinya Kitaoka 120a6e
    , m_panel(panel) {
Shinya Kitaoka 120a6e
  setObjectName("FunctionSegmentViewer");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_pages[0] = new FunctionEmptySegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[1] = new SpeedInOutSegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[2] = new EaseInOutSegmentPage(false, this);
Shinya Kitaoka 120a6e
  m_pages[3] = new EaseInOutSegmentPage(true, this);
Shinya Kitaoka 120a6e
  m_pages[4] = new FunctionEmptySegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[5] = new FunctionExpressionSegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[6] = new FileSegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[7] = new FunctionEmptySegmentPage(this);
Shinya Kitaoka 120a6e
  m_pages[8] = new SimilarShapeSegmentPage(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_typeId[0] = TDoubleKeyframe::Linear;
Shinya Kitaoka 120a6e
  m_typeId[1] = TDoubleKeyframe::SpeedInOut;
Shinya Kitaoka 120a6e
  m_typeId[2] = TDoubleKeyframe::EaseInOut;
Shinya Kitaoka 120a6e
  m_typeId[3] = TDoubleKeyframe::EaseInOutPercentage;
Shinya Kitaoka 120a6e
  m_typeId[4] = TDoubleKeyframe::Exponential;
Shinya Kitaoka 120a6e
  m_typeId[5] = TDoubleKeyframe::Expression;
Shinya Kitaoka 120a6e
  m_typeId[6] = TDoubleKeyframe::File;
Shinya Kitaoka 120a6e
  m_typeId[7] = TDoubleKeyframe::Constant;
Shinya Kitaoka 120a6e
  m_typeId[8] = TDoubleKeyframe::SimilarShape;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_typeCombo = new QComboBox;
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Linear"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Speed In / Speed Out"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Ease In / Ease Out"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Ease In / Ease Out %"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Exponential"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Expression"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("File"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Constant"));
Shinya Kitaoka 120a6e
  m_typeCombo->addItem(tr("Similar Shape"));
Shinya Kitaoka 120a6e
  m_typeCombo->setCurrentIndex(7);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---- common interfaces
Shinya Kitaoka 120a6e
  m_fromFld        = new QLineEdit(this);
Shinya Kitaoka 120a6e
  m_toFld          = new QLineEdit(this);
Shinya Kitaoka 120a6e
  m_paramNameLabel = new QLabel("", this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QLabel *typeLabel = new QLabel(tr("Interpolation:"));
Shinya Kitaoka 120a6e
  typeLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
Shinya Kitaoka 120a6e
  m_stepFld = new LineEdit();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // bottom part: stacked widget
Shinya Kitaoka 120a6e
  m_parametersPanel = new QStackedWidget;
Shinya Kitaoka 120a6e
  m_parametersPanel->setObjectName("FunctionParametersPanel");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < tArrayCount(m_pages); i++)
Shinya Kitaoka 120a6e
    m_parametersPanel->addWidget(m_pages[i]);
Shinya Kitaoka 120a6e
  m_parametersPanel->setCurrentIndex(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // buttons
Shinya Kitaoka 120a6e
  QPushButton *applyButton = new QPushButton(tr("Apply"), this);
Shinya Kitaoka 120a6e
  m_prevCurveButton        = new QPushButton(this);
Shinya Kitaoka 120a6e
  m_nextCurveButton        = new QPushButton(this);
Shinya Kitaoka 120a6e
  m_prevLinkButton         = new QPushButton(this);
Shinya Kitaoka 120a6e
  m_nextLinkButton         = new QPushButton(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----
Shinya Kitaoka 120a6e
  QIntValidator *intValidator = new QIntValidator(1, 100, this);
Shinya Kitaoka 120a6e
  m_stepFld->setValidator(intValidator);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QIntValidator *validator = new QIntValidator(this);
Shinya Kitaoka 120a6e
  validator->setBottom(1);
Shinya Kitaoka 120a6e
  m_fromFld->setValidator(validator);
Shinya Kitaoka 120a6e
  m_toFld->setValidator(validator);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_stepFld->setEnabled(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  applyButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_stepFld->setText("1");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_prevCurveButton->setFixedSize(50, 15);
Shinya Kitaoka 120a6e
  m_nextCurveButton->setFixedSize(50, 15);
Shinya Kitaoka 120a6e
  m_prevCurveButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  m_nextCurveButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  m_prevCurveButton->setStyleSheet("padding:0px;");
Shinya Kitaoka 120a6e
  m_nextCurveButton->setStyleSheet("padding:0px;");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_prevLinkButton->setFixedSize(15, 15);
Shinya Kitaoka 120a6e
  m_nextLinkButton->setFixedSize(15, 15);
Shinya Kitaoka 120a6e
  m_prevLinkButton->setCheckable(true);
Shinya Kitaoka 120a6e
  m_nextLinkButton->setCheckable(true);
Shinya Kitaoka 120a6e
  m_prevLinkButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  m_nextLinkButton->setFocusPolicy(Qt::NoFocus);
Shinya Kitaoka 120a6e
  m_prevLinkButton->setObjectName("FunctionSegmentViewerLinkButton");
Shinya Kitaoka 120a6e
  m_nextLinkButton->setObjectName("FunctionSegmentViewerLinkButton");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---- layout
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QVBoxLayout *mainLayout = new QVBoxLayout();
Shinya Kitaoka 120a6e
  mainLayout->setSpacing(5);
Shinya Kitaoka 120a6e
  mainLayout->setMargin(5);
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    m_topbar                  = new QWidget();
Shinya Kitaoka 120a6e
    QVBoxLayout *topbarLayout = new QVBoxLayout();
Shinya Kitaoka 120a6e
    topbarLayout->setSpacing(5);
Shinya Kitaoka 120a6e
    topbarLayout->setMargin(0);
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      topbarLayout->addWidget(m_paramNameLabel);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QHBoxLayout *upperLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
      upperLay->setSpacing(3);
Shinya Kitaoka 120a6e
      upperLay->setMargin(0);
Shinya Kitaoka 120a6e
      {
Yu Chen da5534
        upperLay->addWidget(new QLabel(tr("From"), this), 0);
Shinya Kitaoka 120a6e
        upperLay->addWidget(m_fromFld, 1);
Shinya Kitaoka 120a6e
        upperLay->addSpacing(3);
Yu Chen da5534
        upperLay->addWidget(new QLabel(tr("To"), this), 0);
Shinya Kitaoka 120a6e
        upperLay->addWidget(m_toFld, 1);
Shinya Kitaoka 120a6e
        upperLay->addSpacing(5);
Yu Chen da5534
        upperLay->addWidget(new QLabel(tr("Step"), this), 0);
Shinya Kitaoka 120a6e
        upperLay->addWidget(m_stepFld, 1);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      topbarLayout->addLayout(upperLay, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      QHBoxLayout *bottomLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
      bottomLay->setSpacing(3);
Shinya Kitaoka 120a6e
      bottomLay->setMargin(0);
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        bottomLay->addWidget(typeLabel, 0);
Shinya Kitaoka 120a6e
        bottomLay->addWidget(m_typeCombo, 1);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      topbarLayout->addLayout(bottomLay, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // end topbar
Shinya Kitaoka 120a6e
    m_topbar->setLayout(topbarLayout);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_topbar, 0);
Shinya Kitaoka 120a6e
    mainLayout->addWidget(m_parametersPanel, 0);
Shinya Kitaoka 120a6e
    mainLayout->addStretch(1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    mainLayout->addWidget(applyButton);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QHBoxLayout *moveLay = new QHBoxLayout();
Shinya Kitaoka 120a6e
    moveLay->setMargin(0);
Shinya Kitaoka 120a6e
    moveLay->setSpacing(0);
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      moveLay->addWidget(m_prevCurveButton, 0);
Shinya Kitaoka 120a6e
      moveLay->addWidget(m_prevLinkButton, 0);
Shinya Kitaoka 120a6e
      moveLay->addStretch(1);
Shinya Kitaoka 120a6e
      moveLay->addWidget(m_nextLinkButton, 0);
Shinya Kitaoka 120a6e
      moveLay->addWidget(m_nextCurveButton, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    mainLayout->addLayout(moveLay, 0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  setLayout(mainLayout);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //---- signal-slot connections
Shinya Kitaoka 120a6e
  bool ret = true;
Shinya Kitaoka 120a6e
  ret      = ret && connect(m_typeCombo, SIGNAL(currentIndexChanged(int)),
Shinya Kitaoka 120a6e
                       m_parametersPanel, SLOT(setCurrentIndex(int)));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_typeCombo, SIGNAL(activated(int)), this,
Shinya Kitaoka 120a6e
                       SLOT(onSegmentTypeChanged(int)));
Shinya Kitaoka 120a6e
  ret = ret && connect(applyButton, SIGNAL(clicked()), this,
Shinya Kitaoka 120a6e
                       SLOT(onApplyButtonPressed()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_prevCurveButton, SIGNAL(clicked()), this,
Shinya Kitaoka 120a6e
                       SLOT(onPrevCurveButtonPressed()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_nextCurveButton, SIGNAL(clicked()), this,
Shinya Kitaoka 120a6e
                       SLOT(onNextCurveButtonPressed()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_prevLinkButton, SIGNAL(clicked()), this,
Shinya Kitaoka 120a6e
                       SLOT(onPrevLinkButtonPressed()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_nextLinkButton, SIGNAL(clicked()), this,
Shinya Kitaoka 120a6e
                       SLOT(onNextLinkButtonPressed()));
Shinya Kitaoka 120a6e
  assert(ret);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_sheet = sheet;
Shinya Kitaoka 120a6e
  refresh();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionSegmentViewer::~FunctionSegmentViewer() {
Shinya Kitaoka 120a6e
  if (m_curve) m_curve->release();
Shinya Kitaoka 120a6e
  m_curve = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::setSegment(TDoubleParam *curve, int segmentIndex) {
Shinya Kitaoka 120a6e
  if (curve != m_curve) {
Shinya Kitaoka 120a6e
    if (m_curve) {
Shinya Kitaoka 120a6e
      m_curve->removeObserver(this);
Shinya Kitaoka 120a6e
      m_curve->release();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_curve = curve;
Shinya Kitaoka 120a6e
    if (m_curve) {
Shinya Kitaoka 120a6e
      m_curve->addRef();
Shinya Kitaoka 120a6e
      m_curve->addObserver(this);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_segmentIndex = segmentIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  refresh();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::setSegmentByFrame(TDoubleParam *curve, int frame) {
Shinya Kitaoka 120a6e
  bool curveSwitched = false;
Shinya Kitaoka 120a6e
  if (curve != m_curve) {
Shinya Kitaoka 120a6e
    curveSwitched = true;
Shinya Kitaoka 120a6e
    if (m_curve) {
Shinya Kitaoka 120a6e
      m_curve->removeObserver(this);
Shinya Kitaoka 120a6e
      m_curve->release();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_curve = curve;
Shinya Kitaoka 120a6e
    if (m_curve) {
Shinya Kitaoka 120a6e
      m_curve->addRef();
Shinya Kitaoka 120a6e
      m_curve->addObserver(this);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool segmentSwitched = false;
Shinya Kitaoka 120a6e
  if (m_curve && (curveSwitched || frame < m_r0 || frame > m_r1)) {
Shinya Kitaoka 120a6e
    int segmentIndex = -1;
Shinya Kitaoka 120a6e
    if (m_curve->isKeyframe(frame)) {
Shinya Kitaoka 120a6e
      int k1 = m_curve->getNextKeyframe(frame);
Shinya Kitaoka 120a6e
      if (k1 >= 1)
Shinya Kitaoka 120a6e
        segmentIndex = k1 - 1;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        int k0                    = m_curve->getPrevKeyframe(frame);
Shinya Kitaoka 120a6e
        if (k0 >= 0) segmentIndex = k0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      segmentIndex = m_curve->getPrevKeyframe(frame);
Shinya Kitaoka 120a6e
      if (m_curve->getNextKeyframe(frame) < 0) segmentIndex = -1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_segmentIndex != segmentIndex) {
Shinya Kitaoka 120a6e
      m_segmentIndex  = segmentIndex;
Shinya Kitaoka 120a6e
      segmentSwitched = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (curveSwitched || segmentSwitched) refresh();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::refresh() {
Shinya Kitaoka 120a6e
  if (m_sheet->isVisible()) {
Shinya Kitaoka 120a6e
    m_paramNameLabel->setText(m_sheet->getSelectedParamName());
Shinya Kitaoka 120a6e
    if (m_sheet->getSelectedParamName().isEmpty()) {
Shinya Kitaoka 120a6e
      m_curve        = 0;
Shinya Kitaoka 120a6e
      m_segmentIndex = -1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_paramNameLabel->setText("");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_curve &&
Shinya Kitaoka 120a6e
      (m_segmentIndex < 0 || m_segmentIndex + 1 >= m_curve->getKeyframeCount()))
Shinya Kitaoka 120a6e
    m_segmentIndex = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_prevCurveButton->setEnabled(false);
Shinya Kitaoka 120a6e
  m_prevLinkButton->setEnabled(false);
Shinya Kitaoka 120a6e
  m_prevCurveButton->setText(" --- ");
Shinya Kitaoka 120a6e
  m_prevLinkButton->setChecked(false);
Shinya Kitaoka 120a6e
  m_nextCurveButton->setEnabled(false);
Shinya Kitaoka 120a6e
  m_nextLinkButton->setEnabled(false);
Shinya Kitaoka 120a6e
  m_nextCurveButton->setText(" --- ");
Shinya Kitaoka 120a6e
  m_nextLinkButton->setChecked(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if some segment is selected
Shinya Kitaoka 120a6e
  if (m_curve && m_segmentIndex >= 0) {
Shinya Kitaoka 120a6e
    m_topbar->show();
Shinya Kitaoka 120a6e
    // m_parametersPanel->show();
Shinya Kitaoka 120a6e
    m_r0 = m_curve->keyframeIndexToFrame(m_segmentIndex);
Shinya Kitaoka 120a6e
    m_r1 = m_curve->keyframeIndexToFrame(m_segmentIndex + 1);
Shinya Kitaoka 120a6e
    m_fromFld->setText(QString::number(m_r0 + 1));
Shinya Kitaoka 120a6e
    m_toFld->setText(QString::number(m_r1 + 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDoubleKeyframe kf = m_curve->getKeyframeAt(m_r0);
Shinya Kitaoka 120a6e
    int pageIndex      = typeToIndex(kf.m_type);
Shinya Kitaoka 120a6e
    m_typeCombo->setEnabled(true);
Shinya Kitaoka 120a6e
    m_typeCombo->setCurrentIndex(pageIndex);
Shinya Kitaoka 120a6e
    if (0 <= pageIndex && pageIndex < tArrayCount(m_pages)) {
Shinya Kitaoka 120a6e
      m_parametersPanel->setCurrentIndex(pageIndex);
Shinya Kitaoka 120a6e
      m_pages[pageIndex]->refresh();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_stepFld->setText(QString::number(kf.m_step));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--- 前後のキーフレームの表示を更新 ---*/
Shinya Kitaoka 120a6e
    // Prev
Shinya Kitaoka 120a6e
    if (m_segmentIndex != 0) {
Shinya Kitaoka 120a6e
      TDoubleKeyframe prevKf = m_curve->getKeyframe(m_segmentIndex - 1);
Shinya Kitaoka 120a6e
      m_prevCurveButton->setEnabled(true);
Shinya Kitaoka 120a6e
      m_prevLinkButton->setEnabled(true);
Shinya Kitaoka 120a6e
      m_prevCurveButton->setText(tr("< ") + typeToString(prevKf.m_type));
Shinya Kitaoka 120a6e
      m_prevLinkButton->setChecked(kf.m_linkedHandles);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // Next
Shinya Kitaoka 120a6e
    if (m_curve->getKeyframeCount() - 2 != m_segmentIndex) {
Shinya Kitaoka 120a6e
      TDoubleKeyframe nextKf = m_curve->getKeyframe(m_segmentIndex + 1);
Shinya Kitaoka 120a6e
      m_nextCurveButton->setEnabled(true);
Shinya Kitaoka 120a6e
      m_nextLinkButton->setEnabled(true);
Shinya Kitaoka 120a6e
      m_nextCurveButton->setText(typeToString(nextKf.m_type) + tr(" >"));
Shinya Kitaoka 120a6e
      m_nextLinkButton->setChecked(nextKf.m_linkedHandles);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /* ---
Shinya Kitaoka 120a6e
Segmentが選ばれていない場合
Shinya Kitaoka 120a6e
既にキーフレームが有る場合は、選択範囲上下どちらかと最近傍のキーフレームでSegmentを作る
Shinya Kitaoka 120a6e
キーフレームが無い場合は、選択範囲を入力
Shinya Kitaoka 120a6e
ただし選択範囲が1フレームのときは、そのフレームから15フレームの範囲で入力
Shinya Kitaoka 120a6e
---*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    m_stepFld->setText("1");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_parametersPanel->setCurrentIndex(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_typeCombo->setCurrentIndex(7);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_r0 = m_r1 = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QRect selectedCells = m_sheet->getSelectedCells();
Shinya Kitaoka 120a6e
    /*--- 選択範囲が空のとき、もしくはカーブが選ばれていないとき ---*/
Shinya Kitaoka 120a6e
    if (selectedCells.isEmpty() || !m_curve) {
Shinya Kitaoka 120a6e
      m_typeCombo->setEnabled(false);
Shinya Kitaoka 120a6e
      m_fromFld->setText("");
Shinya Kitaoka 120a6e
      m_toFld->setText("");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*--- 何かカーブが選択されている ---*/
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      m_typeCombo->setEnabled(true);
Shinya Kitaoka 120a6e
      int s0 = selectedCells.top();
Shinya Kitaoka 120a6e
      int s1 = selectedCells.bottom();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*--- セグメントの上側が選択されているとき ---*/
Shinya Kitaoka 120a6e
      int next = m_curve->getNextKeyframe(s0);
Shinya Kitaoka 120a6e
      if (next >= 0) {
Shinya Kitaoka 120a6e
        m_fromFld->setText(QString::number(s0 + 1));
Shinya Kitaoka 120a6e
        m_toFld->setText(
Shinya Kitaoka 120a6e
            QString::number(m_curve->getKeyframe(next).m_frame + 1));
Shinya Kitaoka 120a6e
        //*--- 前後のキーフレームの表示を更新 ---*/
Shinya Kitaoka 120a6e
        if (m_curve->getKeyframeCount() >= 2) {
Shinya Kitaoka 120a6e
          TDoubleKeyframe nextKf = m_curve->getKeyframe(next);
Shinya Kitaoka 120a6e
          m_nextCurveButton->setEnabled(true);
Shinya Kitaoka 120a6e
          m_nextLinkButton->setEnabled(true);
Shinya Kitaoka 120a6e
          m_nextCurveButton->setText(typeToString(nextKf.m_type) + tr(" >"));
Shinya Kitaoka 120a6e
          m_nextLinkButton->setChecked(nextKf.m_linkedHandles);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        /*--- セグメントの下側が選択されているとき ---*/
Shinya Kitaoka 120a6e
        int prev = m_curve->getPrevKeyframe(s0);
Shinya Kitaoka 120a6e
        if (prev >= 0) {
Shinya Kitaoka 120a6e
          m_fromFld->setText(
Shinya Kitaoka 120a6e
              QString::number(m_curve->getKeyframe(prev).m_frame + 1));
Shinya Kitaoka 120a6e
          m_toFld->setText(QString::number(s1 + 1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          //*--- 前後のキーフレームの表示を更新 ---*/
Shinya Kitaoka 120a6e
          if (prev > 0) {
Shinya Kitaoka 120a6e
            TDoubleKeyframe kf     = m_curve->getKeyframe(prev);
Shinya Kitaoka 120a6e
            TDoubleKeyframe prevKf = m_curve->getKeyframe(prev - 1);
Shinya Kitaoka 120a6e
            m_prevCurveButton->setEnabled(true);
Shinya Kitaoka 120a6e
            m_prevLinkButton->setEnabled(true);
Shinya Kitaoka 120a6e
            m_prevCurveButton->setText(tr("< ") + typeToString(prevKf.m_type));
Shinya Kitaoka 120a6e
            m_prevLinkButton->setChecked(kf.m_linkedHandles);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        /*--- キーフレームが1個もない場合 ---*/
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          if (s0 == s1) {
Shinya Kitaoka 120a6e
            int endFrame;
Shinya Kitaoka 120a6e
            if (m_xshHandle) {
Shinya Kitaoka 120a6e
              endFrame = m_xshHandle->getXsheet()->getFrameCount();
Shinya Kitaoka 120a6e
              /*---
Shinya Kitaoka 120a6e
               * xsheetに何もLevelがないとき,又は選択フレームがXsheetをはみだしているとき
Shinya Kitaoka 120a6e
               * ---*/
Shinya Kitaoka 120a6e
              if (endFrame == 0 || s0 + 1 >= endFrame) endFrame = s0 + 16;
Shinya Kitaoka 120a6e
            } else {
Shinya Kitaoka 120a6e
              endFrame = s0 + 16;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            m_fromFld->setText(QString::number(s0 + 1));
Shinya Kitaoka 120a6e
            m_toFld->setText(QString::number(endFrame));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            m_fromFld->setText(QString::number(s0 + 1));
Shinya Kitaoka 120a6e
            m_toFld->setText(QString::number(s1 + 1));
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onCurveChanged() {
Shinya Kitaoka 120a6e
  int pageIndex = m_typeCombo->currentIndex();
Shinya Kitaoka 120a6e
  if (0 <= pageIndex && pageIndex < tArrayCount(m_pages))
Shinya Kitaoka 120a6e
    m_pages[pageIndex]->refresh();
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onStepFieldChanged(const QString &text) {
Shinya Kitaoka 120a6e
  if (!segmentIsValid()) return;
Shinya Kitaoka 120a6e
  int step             = 1;
Shinya Kitaoka 120a6e
  if (text != "") step = text.toInt();
Shinya Kitaoka 120a6e
  if (step < 1) step   = 1;
Shinya Kitaoka 120a6e
  KeyframeSetter setter(m_curve, m_segmentIndex);
Shinya Kitaoka 120a6e
  setter.setStep(step);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FunctionSegmentViewer::typeToIndex(int typeId) const {
Shinya Kitaoka 120a6e
  for (int i = 0; i < tArrayCount(m_typeId); i++)
Shinya Kitaoka 120a6e
    if (m_typeId[i] == typeId) return i;
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionSegmentViewer::segmentIsValid() const {
Shinya Kitaoka 120a6e
  return m_curve && 0 <= m_segmentIndex &&
Shinya Kitaoka 120a6e
         m_segmentIndex + 1 < m_curve->getKeyframeCount();
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
/*----
Toshihiro Shimizu 890ddd
 すでにカーブがあり元のTypeの場合→本来の値に更新(refresh)
Toshihiro Shimizu 890ddd
 EaseIn/Out⇔EaseIn/Out(%)→値を変換
Toshihiro Shimizu 890ddd
 その他→各ページのイニシャライズ(ExpressionはGrammerを入れる)
Toshihiro Shimizu 890ddd
---*/
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onSegmentTypeChanged(int typeIndex) {
Shinya Kitaoka 120a6e
  if (!m_curve) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- すでにカーブがあり元のTypeの場合→カーブの情報本来の値に更新(refresh)
Shinya Kitaoka 120a6e
   * ---*/
Shinya Kitaoka 120a6e
  if (m_segmentIndex >= 0) {
Shinya Kitaoka 120a6e
    TDoubleKeyframe::Type currentType =
Shinya Kitaoka 120a6e
        m_curve->getKeyframe(m_segmentIndex).m_type;
Shinya Kitaoka 120a6e
    if (typeIndex == typeToIndex(currentType)) {
Shinya Kitaoka 120a6e
      m_pages[typeIndex]->refresh();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int segmentLength = m_toFld->text().toInt() - m_fromFld->text().toInt();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pages[typeIndex]->init(segmentLength);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onApplyButtonPressed() {
Shinya Kitaoka 120a6e
  /*--- カーブを何も掴んでいなればreturn ---*/
Shinya Kitaoka 120a6e
  if (!m_curve) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- パラメータの現状を取得 ---*/
Shinya Kitaoka 120a6e
  int fromFrame = m_fromFld->text().toInt() - 1;
Shinya Kitaoka 120a6e
  int toFrame   = m_toFld->text().toInt() - 1;
Shinya Kitaoka 120a6e
  TDoubleKeyframe::Type comboType =
Shinya Kitaoka 120a6e
      (TDoubleKeyframe::Type)indexToType(m_typeCombo->currentIndex());
Shinya Kitaoka 120a6e
  int step = m_stepFld->text().toInt();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD speedIn(0, 0);
Shinya Kitaoka 120a6e
  TPointD speedOut(0, 0);
Shinya Kitaoka 120a6e
  std::string expressionText = "";
Shinya Kitaoka 120a6e
  std::string unitName       = "inch";
Shinya Kitaoka 120a6e
  TDoubleKeyframe::FileParams fileParams;
Shinya Kitaoka 120a6e
  double similarShapeOffset = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 現在のindexに合わせて、必要なパラメータをGUIから持ってきて格納 ---*/
Shinya Kitaoka 120a6e
  switch (comboType) {
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::Linear:
Shinya Kitaoka 120a6e
    // no param
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::SpeedInOut: {
Shinya Kitaoka 120a6e
    SpeedInOutSegmentPage *page = qobject_cast<speedinoutsegmentpage *="">(</speedinoutsegmentpage>
Shinya Kitaoka 120a6e
        m_parametersPanel->currentWidget());
Shinya Kitaoka 120a6e
    if (page) page->getGuiValues(speedIn, speedOut);
Shinya Kitaoka 120a6e
  } break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::EaseInOut:
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::EaseInOutPercentage: {
Shinya Kitaoka 120a6e
    EaseInOutSegmentPage *page = qobject_cast<easeinoutsegmentpage *="">(</easeinoutsegmentpage>
Shinya Kitaoka 120a6e
        m_parametersPanel->currentWidget());
Shinya Kitaoka 120a6e
    if (page) page->getGuiValues(speedIn, speedOut);
Shinya Kitaoka 120a6e
  } break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::Exponential:
Shinya Kitaoka 120a6e
    // no param
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::Expression: {
Shinya Kitaoka 120a6e
    FunctionExpressionSegmentPage *page =
Shinya Kitaoka 120a6e
        qobject_cast<functionexpressionsegmentpage *="">(</functionexpressionsegmentpage>
Shinya Kitaoka 120a6e
            m_parametersPanel->currentWidget());
Shinya Kitaoka 120a6e
    if (page) {
Shinya Kitaoka 120a6e
      bool ok = page->getGuiValues(expressionText, unitName);
Shinya Kitaoka 120a6e
      if (!ok) return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::File: {
Shinya Kitaoka 120a6e
    FileSegmentPage *page =
Shinya Kitaoka 120a6e
        dynamic_cast<filesegmentpage *="">(m_parametersPanel->currentWidget());</filesegmentpage>
Shinya Kitaoka 120a6e
    if (page) page->getGuiValues(fileParams, unitName);
Shinya Kitaoka 120a6e
  } break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::None:
Shinya Kitaoka 120a6e
    // no param
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TDoubleKeyframe::SimilarShape: {
Shinya Kitaoka 120a6e
    SimilarShapeSegmentPage *page = qobject_cast<similarshapesegmentpage *="">(</similarshapesegmentpage>
Shinya Kitaoka 120a6e
        m_parametersPanel->currentWidget());
Shinya Kitaoka 120a6e
    if (page) page->getGuiValues(expressionText, similarShapeOffset);
Shinya Kitaoka 120a6e
  } break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- from -
Shinya Kitaoka 120a6e
   * toに合わせてキーフレームを作成しようと試みる。すでに有る場合はスキップ
Shinya Kitaoka 120a6e
   * ---*/
Shinya Kitaoka 120a6e
  if (fromFrame < 0) fromFrame        = 0;
Shinya Kitaoka 120a6e
  if (toFrame < 0) toFrame            = 0;
Shinya Kitaoka 120a6e
  if (fromFrame >= toFrame) fromFrame = toFrame + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_curve->isKeyframe(fromFrame))
Shinya Kitaoka 120a6e
    KeyframeSetter::setValue(m_curve, fromFrame, m_curve->getValue(fromFrame));
Shinya Kitaoka 120a6e
  if (!m_curve->isKeyframe(toFrame))
Shinya Kitaoka 120a6e
    KeyframeSetter::setValue(m_curve, toFrame, m_curve->getValue(toFrame));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- 現在のSegmentIndexを更新 ---*/
Shinya Kitaoka 120a6e
  m_segmentIndex = m_curve->getClosestKeyframe(fromFrame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--- パラメータを一括で設定 ---*/
Shinya Kitaoka 120a6e
  KeyframeSetter setter(m_curve, m_segmentIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_panel) setter.setPixelRatio(m_panel->getPixelRatio(m_curve));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  setter.setAllParams(step, comboType, speedIn, speedOut, expressionText,
Shinya Kitaoka 120a6e
                      unitName, fileParams, similarShapeOffset);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// for displaying the types of neighbor segments
Shinya Kitaoka 120a6e
QString FunctionSegmentViewer::typeToString(int typeId) const {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < tArrayCount(m_typeId); i++)
Shinya Kitaoka 120a6e
    if (m_typeId[i] == typeId) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (i) {
Shinya Kitaoka 120a6e
  case 0:
Shinya Kitaoka 120a6e
    return tr("Linear");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    return tr("Speed");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    return tr("Ease");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 3:
Shinya Kitaoka 120a6e
    return tr("Ease%");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    return tr("Expo");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 5:
Shinya Kitaoka 120a6e
    return tr("Expr");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 6:
Shinya Kitaoka 120a6e
    return tr("File");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 7:
Shinya Kitaoka 120a6e
    return tr("Const");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 8:
Shinya Kitaoka 120a6e
    return tr("Similar");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    return tr("????");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onPrevCurveButtonPressed() {
Shinya Kitaoka 120a6e
  if (!m_curve) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_segmentIndex == 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int currentKeyIndex;
Shinya Kitaoka 120a6e
  if (m_segmentIndex > 0) currentKeyIndex = m_segmentIndex;
Shinya Kitaoka 120a6e
  /*--- Segmentが選択されていない→Segmentの下側が選ばれているはず ---*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    QRect selectedCells = m_sheet->getSelectedCells();
Shinya Kitaoka 120a6e
    if (selectedCells.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    currentKeyIndex = m_curve->getPrevKeyframe(selectedCells.top());
Shinya Kitaoka 120a6e
    if (currentKeyIndex != m_curve->getKeyframeCount() - 1) return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int col = m_sheet->getColumnIndexByCurve(m_curve);
Shinya Kitaoka 120a6e
  /*--- Sheet上にCurveが表示されていない場合はcolに-1が返る ---*/
Shinya Kitaoka 120a6e
  if (col < 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDoubleKeyframe currentKey = m_curve->getKeyframe(currentKeyIndex);
Shinya Kitaoka 120a6e
  TDoubleKeyframe prevKey    = m_curve->getKeyframe(currentKeyIndex - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int r0 = (int)prevKey.m_frame;
Shinya Kitaoka 120a6e
  int r1 = (int)currentKey.m_frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_sheet->getSelection()->selectSegment(m_curve, currentKeyIndex - 1,
Shinya Kitaoka 120a6e
                                         QRect(col, r0, 1, r1 - r0 + 1));
Shinya Kitaoka 120a6e
  m_sheet->updateAll();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onNextCurveButtonPressed() {
Shinya Kitaoka 120a6e
  if (!m_curve) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_segmentIndex == m_curve->getKeyframeCount() - 2) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int currentKeyIndex;
Shinya Kitaoka 120a6e
  if (m_segmentIndex >= 0) {
Shinya Kitaoka 120a6e
    currentKeyIndex = m_segmentIndex;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- Segmentが選択されていない→Segmentの上側が選ばれているはず ---*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    QRect selectedCells = m_sheet->getSelectedCells();
Shinya Kitaoka 120a6e
    if (selectedCells.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    currentKeyIndex = m_curve->getNextKeyframe(selectedCells.top());
Shinya Kitaoka 120a6e
    if (currentKeyIndex != 0) return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int col = m_sheet->getColumnIndexByCurve(m_curve);
Shinya Kitaoka 120a6e
  /*--- Sheet上にCurveが表示されていない場合はcolに-1が返る ---*/
Shinya Kitaoka 120a6e
  if (col < 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDoubleKeyframe nextKey     = m_curve->getKeyframe(currentKeyIndex + 1);
Shinya Kitaoka 120a6e
  TDoubleKeyframe nextNextKey = m_curve->getKeyframe(currentKeyIndex + 2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int r0 = (int)nextKey.m_frame;
Shinya Kitaoka 120a6e
  int r1 = (int)nextNextKey.m_frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_sheet->getSelection()->selectSegment(m_curve, currentKeyIndex + 1,
Shinya Kitaoka 120a6e
                                         QRect(col, r0, 1, r1 - r0 + 1));
Shinya Kitaoka 120a6e
  m_sheet->updateAll();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onPrevLinkButtonPressed() {
Shinya Kitaoka 120a6e
  if (m_prevLinkButton->isChecked())
Shinya Kitaoka 120a6e
    KeyframeSetter(m_curve, m_segmentIndex).linkHandles();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    KeyframeSetter(m_curve, m_segmentIndex).unlinkHandles();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionSegmentViewer::onNextLinkButtonPressed() {
Shinya Kitaoka 120a6e
  if (m_nextLinkButton->isChecked())
Shinya Kitaoka 120a6e
    KeyframeSetter(m_curve, m_segmentIndex + 1).linkHandles();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    KeyframeSetter(m_curve, m_segmentIndex + 1).unlinkHandles();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionSegmentViewer::anyWidgetHasFocus() {
Shinya Kitaoka 120a6e
  return m_topbar->hasFocus() || m_fromFld->hasFocus() || m_toFld->hasFocus() ||
Shinya Kitaoka 120a6e
         m_typeCombo->hasFocus() || m_stepFld->hasFocus() ||
Shinya Kitaoka 120a6e
         m_prevCurveButton->hasFocus() || m_nextCurveButton->hasFocus() ||
Shinya Kitaoka 120a6e
         m_prevLinkButton->hasFocus() || m_nextLinkButton->hasFocus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! in order to avoid FunctionViewer to get focus while editing the expression
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
bool FunctionSegmentViewer::isExpressionPageActive() {
Shinya Kitaoka 120a6e
  return (m_typeCombo->currentIndex() == 5);
Toshihiro Shimizu 890ddd
}