Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/functiontoolbar.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/doublefield.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/functionkeyframenavigator.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/functionselection.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/framenavigator.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/menubarcommand.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/doubleparamcmd.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qlabel></qlabel>
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
   * two states: curve_defined / curve_not_defined
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
   * three widgets: value_fld, frame_nav, keyframe_nav
Toshihiro Shimizu 890ddd
                    (if curve_not_defined only keyframe_nav is visible)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
   * user actions
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
     - value_fld changed / keyframe_nav changed (key icon) => modify current
Shinya Kitaoka 120a6e
   curve
Shinya Kitaoka 120a6e
     - frame_nav changed / keyframe_nav changed (arrows) => modify the 'extern'
Shinya Kitaoka 120a6e
   frame
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
   * 'extern' events:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
     - 'extern' frame changed => update fields
Toshihiro Shimizu 890ddd
     - curve selected => update fields (and possibly change status)
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionToolbar::FunctionToolbar(QWidget *parent)
Shinya Kitaoka 120a6e
    : DVGui::ToolBar(parent), m_frameHandle(0), m_curve(0), m_selection(0) {
Shinya Kitaoka 120a6e
  setFixedHeight(28);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_valueToolbar    = new DVGui::ToolBar();
Shinya Kitaoka 120a6e
  m_keyframeToolbar = new DVGui::ToolBar();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // value field
Shinya Kitaoka 120a6e
  m_valueToolbar->addWidget(new QLabel(tr("Value")));
Shinya Kitaoka 120a6e
  m_valueFld = new DVGui::MeasuredDoubleLineEdit();
Shinya Kitaoka 120a6e
  // frame navigator
Shinya Kitaoka 120a6e
  m_frameNavigator = new FrameNavigator(this);
Shinya Kitaoka 120a6e
  // keyframe navigator
Shinya Kitaoka 120a6e
  m_keyframeNavigator          = new FunctionKeyframeNavigator(this);
Shinya Kitaoka 120a6e
  QWidget *space               = new QWidget(this);
Shinya Kitaoka 120a6e
  DVGui::ToolBar *spaceToolBar = new DVGui::ToolBar();
Shinya Kitaoka 120a6e
  spaceToolBar->addWidget(space);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_valueFld->setStyleSheet("height:14px;margin-right:5px;margin-top:2px;");
Shinya Kitaoka 120a6e
  space->setMinimumHeight(22);
Shinya Kitaoka 120a6e
  space->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QIcon toggleIcon      = createQIconOnOffPNG("swap", false);
Shinya Kitaoka 120a6e
  QAction *toggleAction = new QAction(tr("&Function Editor Toggle"), this);
Shinya Kitaoka 120a6e
  assert(toggleAction);
Shinya Kitaoka 120a6e
  toggleAction->setIcon(toggleIcon);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----layout
Shinya Kitaoka 120a6e
  m_valueFldAction          = addWidget(m_valueToolbar);
Shinya Kitaoka 120a6e
  m_keyframeNavigatorAction = addWidget(m_keyframeToolbar);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_valueToolbar->addWidget(m_valueFld);
Shinya Kitaoka 120a6e
  m_valueToolbar->addSeparator();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_keyframeToolbar->addWidget(m_keyframeNavigator);
Shinya Kitaoka 120a6e
  m_keyframeToolbar->addSeparator();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  addWidget(m_frameNavigator);
Shinya Kitaoka 120a6e
  addSeparator();
Shinya Kitaoka 120a6e
  addWidget(spaceToolBar);
Shinya Kitaoka 120a6e
  addSeparator();
Shinya Kitaoka 120a6e
  addAction(toggleAction);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret = connect(m_valueFld, SIGNAL(valueChanged()), this,
Shinya Kitaoka 120a6e
                     SLOT(onValueFieldChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(m_frameNavigator, SIGNAL(frameSwitched()), this,
Shinya Kitaoka 120a6e
                       SLOT(onNavFrameSwitched()));
Shinya Kitaoka 120a6e
  ret = ret && connect(toggleAction, SIGNAL(triggered()), this,
Shinya Kitaoka 120a6e
                       SIGNAL(numericalColumnToggled()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_valueFldAction->setVisible(false);
Shinya Kitaoka 120a6e
  m_keyframeNavigatorAction->setVisible(false);
Shinya Kitaoka 120a6e
  assert(ret);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FunctionToolbar::~FunctionToolbar() {
Shinya Kitaoka 120a6e
  if (m_curve) {
Shinya Kitaoka 120a6e
    m_curve->removeObserver(this);
Shinya Kitaoka 120a6e
    m_curve->release();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FunctionToolbar::anyWidgetHasFocus() {
Shinya Kitaoka 120a6e
  return hasFocus() || m_valueToolbar->hasFocus() ||
Shinya Kitaoka 120a6e
         m_keyframeToolbar->hasFocus() || m_valueFld->hasFocus() ||
Shinya Kitaoka 120a6e
         m_frameNavigator->anyWidgetHasFocus() ||
Shinya Kitaoka 120a6e
         m_keyframeNavigator->hasFocus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::setCurve(TDoubleParam *curve) {
Shinya Kitaoka 120a6e
  if (curve == m_curve) return;
Shinya Kitaoka 120a6e
  bool curveDefined = curve != 0;
Shinya Kitaoka 120a6e
  m_valueFldAction->setVisible(curveDefined);
Shinya Kitaoka 120a6e
  m_keyframeNavigatorAction->setVisible(curveDefined);
Shinya Kitaoka 120a6e
  m_keyframeNavigator->setCurve(curve);
Shinya Kitaoka 120a6e
  if (curve) {
Shinya Kitaoka 120a6e
    curve->addObserver(this);
Shinya Kitaoka 120a6e
    curve->addRef();
Shinya Kitaoka 120a6e
  }
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_valueFld->setMeasure(m_curve->getMeasureName());
Shinya Kitaoka 120a6e
    setFrame(m_frameNavigator->getFrame());
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_valueFld->setMeasure("");
Shinya Kitaoka 120a6e
    m_valueFld->setValue(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::setFrame(double frame) {
Shinya Kitaoka 120a6e
  m_frameNavigator->setFrame(tround(frame), false);
Shinya Kitaoka 120a6e
  if (m_curve)
Shinya Kitaoka 120a6e
    m_valueFld->setValue(m_curve->getValue(frame));
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_valueFld->setValue(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::onValueFieldChanged() {
Shinya Kitaoka 120a6e
  if (!m_curve) return;
Shinya Kitaoka 120a6e
  int frame     = m_frameNavigator->getFrame();
Shinya Kitaoka 120a6e
  double value  = m_valueFld->getValue();
Shinya Kitaoka 120a6e
  double fValue = m_curve->getValue(frame);
Shinya Kitaoka 120a6e
  if (value == fValue) return;
Shinya Kitaoka 120a6e
  KeyframeSetter::setValue(m_curve, frame, value);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::onFrameSwitched() { setFrame(m_frameHandle->getFrame()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::onNavFrameSwitched() {
Shinya Kitaoka 120a6e
  if (m_frameHandle) m_frameHandle->setFrame(m_frameNavigator->getFrame());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::onSelectionChanged() {
Shinya Kitaoka 120a6e
  if (m_selection) {
Shinya Kitaoka 120a6e
    if (m_selection->getSelectedKeyframeCount() == 1) {
Shinya Kitaoka 120a6e
      QPair<tdoubleparam *,="" int=""> k = m_selection->getSelectedKeyframe(0);</tdoubleparam>
Shinya Kitaoka 120a6e
      if (k.first == m_curve) {
Shinya Kitaoka 120a6e
        int frame = m_curve->keyframeIndexToFrame(k.second);
Shinya Kitaoka 120a6e
        setFrame(frame);
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (m_selection->getSelectedKeyframeCount() > 1) {
Shinya Kitaoka 120a6e
      setFrame(m_frameHandle->getFrame());
Shinya Kitaoka 120a6e
      m_valueFld->setText("");
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_frameHandle && m_curve)
Shinya Kitaoka 120a6e
    setFrame(m_frameHandle->getFrame());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_valueFld->setText("");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::setFrameHandle(TFrameHandle *frameHandle) {
Shinya Kitaoka 120a6e
  if (m_frameHandle) m_frameHandle->disconnect(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_frameHandle = frameHandle;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_frameHandle)
Shinya Kitaoka 120a6e
    connect(m_frameHandle, SIGNAL(frameSwitched()), this,
Shinya Kitaoka 120a6e
            SLOT(onFrameSwitched()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_keyframeNavigator->setFrameHandle(frameHandle);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::setSelection(FunctionSelection *selection) {
Shinya Kitaoka 120a6e
  if (m_selection != selection) {
Shinya Kitaoka 120a6e
    if (m_selection)
Shinya Kitaoka 120a6e
      disconnect(m_selection, SIGNAL(selectionChanged()), this,
Shinya Kitaoka 120a6e
                 SLOT(onSelectionChanged()));
Shinya Kitaoka 120a6e
    m_selection = selection;
Shinya Kitaoka 120a6e
    if (m_selection)
Shinya Kitaoka 120a6e
      connect(m_selection, SIGNAL(selectionChanged()), this,
Shinya Kitaoka 120a6e
              SLOT(onSelectionChanged()));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FunctionToolbar::onChange(const TParamChange &) {
Shinya Kitaoka 120a6e
  m_keyframeNavigator->update();
Toshihiro Shimizu 890ddd
}