Blob Blame Raw


#include "scenesettingspopup.h"

// Tnz6 includes
#include "menubarcommandids.h"
#include "previewer.h"
#include "tapp.h"

// TnzQt includes
#include "toonzqt/menubarcommand.h"

// TnzLib includes
#include "toonz/txsheet.h"
#include "toonz/tscenehandle.h"
#include "toonz/txsheethandle.h"
#include "toonz/sceneproperties.h"
#include "toonz/toonzscene.h"
#include "toonz/preferences.h"
#include "toutputproperties.h"

// TnzBase includes
#include "tunit.h"

// TnzCore includes
#include "trop.h"

// Qt includes
#include <QLayout>
#include <QComboBox>
#include <QLabel>
#include <QApplication>
#include <QMainWindow>
#include <QPainter>
#include <QPushButton>

using namespace DVGui;

//-----------------------------------------------------------------------------

namespace {

const int labelSize = 110;

//-----------------------------------------------------------------------------

class EditCellMarkUndo final : public TUndo {
  int m_id;
  TSceneProperties::CellMark m_markBefore, m_markAfter;

  EditCellMarkUndo(int id) : m_id(id) {
    m_markBefore = TApp::instance()
                       ->getCurrentScene()
                       ->getScene()
                       ->getProperties()
                       ->getCellMark(id);
  }

public:
  EditCellMarkUndo(int id, TPixel32 color) : EditCellMarkUndo(id) {
    m_markAfter = {m_markBefore.name, color};
  }
  EditCellMarkUndo(int id, QString name) : EditCellMarkUndo(id) {
    m_markAfter = {name, m_markBefore.color};
  }

  void set(const TSceneProperties::CellMark &mark) const {
    TApp::instance()
        ->getCurrentScene()
        ->getScene()
        ->getProperties()
        ->setCellMark(mark, m_id);
    TApp::instance()->getCurrentScene()->notifySceneChanged();
  }

  void undo() const override { set(m_markBefore); }

  void redo() const override { set(m_markAfter); }

  int getSize() const override { return sizeof *this; }

  QString getHistoryString() override {
    return QObject::tr("Edit Cell Mark #%1").arg(QString::number(m_id));
  }
};

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
}  //  namespace
//-----------------------------------------------------------------------------

/*
class CheckBoardRect final : public QWidget
{
TRaster32P m_ras;

public:
CheckBoardRect(QWidget *parent, int sizeX, int sizeY)
        : m_ras(sizeX,sizeY)
  {
  setFixedSize(sizeX,sizeY);
  setColors(TPixel32(0, 0, 0), TPixel32(255, 255, 255));
  }
void setColors(const TPixel32 &color1, const TPixel32 &color2)
  {
  TRop::checkBoard(m_ras, color1, color2, TDimensionD(m_ras->getLx()/8,
m_ras->getLy()/8),TPointD(0, 0));
  update();
  }
protected:
void paintEvent(QPaintEvent *event)
  {
        QPainter painter(this);
        QImage img(m_ras->getRawData(), m_ras->getLx(), m_ras->getLy(),
QImage::Format_ARGB32);
  painter.drawImage(0,0,img);
  }
};
*/

//=============================================================================
// CellMarksPopup
//-----------------------------------------------------------------------------

CellMarksPopup::CellMarksPopup(QWidget *parent) : QDialog(parent) {
  setWindowTitle(tr("Cell Marks Settings"));

  QList<TSceneProperties::CellMark> marks = TApp::instance()
                                                ->getCurrentScene()
                                                ->getScene()
                                                ->getProperties()
                                                ->getCellMarks();

  QGridLayout *layout = new QGridLayout();
  layout->setMargin(10);
  layout->setHorizontalSpacing(5);
  layout->setVerticalSpacing(10);
  {
    int id = 0;
    for (auto mark : marks) {
      ColorField *colorF = new ColorField(this, false, mark.color, 20);
      colorF->hideChannelsFields(true);
      QLineEdit *nameF = new QLineEdit(mark.name, this);
      m_fields.append({id, colorF, nameF});

      int row = layout->rowCount();

      layout->addWidget(new QLabel(QString("%1:").arg(id), this), row, 0,
                        Qt::AlignRight | Qt::AlignVCenter);

      layout->addWidget(colorF, row, 1);
      layout->addWidget(nameF, row, 2);

      connect(colorF, SIGNAL(colorChanged(const TPixel32 &, bool)), this,
              SLOT(onColorChanged(const TPixel32 &, bool)));
      connect(nameF, SIGNAL(editingFinished()), this, SLOT(onNameChanged()));
      id++;
    }
  }
  layout->setColumnStretch(2, 1);
  setLayout(layout);
}

void CellMarksPopup::update() {
  QList<TSceneProperties::CellMark> marks = TApp::instance()
                                                ->getCurrentScene()
                                                ->getScene()
                                                ->getProperties()
                                                ->getCellMarks();
  assert(marks.count() == m_fields.count());
  int id = 0;
  for (auto mark : marks) {
    assert(m_fields[id].id == id);
    m_fields[id].colorField->setColor(mark.color);
    m_fields[id].nameField->setText(mark.name);
    id++;
  }
}

void CellMarksPopup::onColorChanged(const TPixel32 &color, bool isDragging) {
  if (isDragging) return;
  // obtain id
  int id             = -1;
  ColorField *colorF = qobject_cast<ColorField *>(sender());
  for (auto field : m_fields) {
    if (field.colorField == colorF) {
      id = field.id;
      break;
    }
  }
  if (id < 0) return;

  // return if the value is unchanged
  TPixel32 oldColor = TApp::instance()
                          ->getCurrentScene()
                          ->getScene()
                          ->getProperties()
                          ->getCellMark(id)
                          .color;
  if (color == oldColor) return;

  EditCellMarkUndo *undo = new EditCellMarkUndo(id, color);
  undo->redo();
  TUndoManager::manager()->add(undo);
}

void CellMarksPopup::onNameChanged() {
  // obtain id
  int id           = -1;
  QLineEdit *nameF = qobject_cast<QLineEdit *>(sender());
  for (auto field : m_fields) {
    if (field.nameField == nameF) {
      id = field.id;
      break;
    }
  }
  if (id < 0) return;

  // return if the value is unchanged
  QString oldName = TApp::instance()
                        ->getCurrentScene()
                        ->getScene()
                        ->getProperties()
                        ->getCellMark(id)
                        .name;
  if (nameF->text() == oldName) return;
  // reject empty string
  if (nameF->text().isEmpty()) {
    nameF->setText(oldName);
    return;
  }

  EditCellMarkUndo *undo = new EditCellMarkUndo(id, nameF->text());
  undo->redo();
  TUndoManager::manager()->add(undo);
}

//=============================================================================
// SceneSettingsPopup
//-----------------------------------------------------------------------------

SceneSettingsPopup::SceneSettingsPopup()
    : QDialog(TApp::instance()->getMainWindow()), m_cellMarksPopup(nullptr) {
  setWindowTitle(tr("Scene Settings"));
  setObjectName("SceneSettings");
  TSceneProperties *sprop = getProperties();

  // Frame Rate
  double frameRate = sprop->getOutputProperties()->getFrameRate();
  m_frameRateFld   = new DoubleLineEdit(this, frameRate);
  m_frameRateFld->setRange(1, 100);
  m_frameRateFld->setDecimals(2);

  // Camera BG color
  m_bgColorFld = new ColorField(this, true, sprop->getBgColor());

  // Field Guide Size - A/R
  int fieldGuideSize = sprop->getFieldGuideSize();
  m_fieldGuideFld    = new DVGui::IntLineEdit(this, fieldGuideSize, 0, 50);
  m_aspectRatioFld   = new DoubleLineEdit(this, 1.38);
  m_aspectRatioFld->setRange(-10000.0, 10000.0);
  m_aspectRatioFld->setDecimals(5);

  // Image Subsampling  - Tlv Subsampling
  int fullcolorSubsampling = sprop->getFullcolorSubsampling();
  m_fullcolorSubsamplingFld =
      new DVGui::IntLineEdit(this, fullcolorSubsampling, 1);

  int tlvSubsampling  = sprop->getTlvSubsampling();
  m_tlvSubsamplingFld = new DVGui::IntLineEdit(this, tlvSubsampling, 1);

  // Marker Interval - Start Frame
  int distance, offset, secDistance;
  sprop->getMarkers(distance, offset, secDistance);
  m_markerIntervalFld = new DVGui::IntLineEdit(this, distance, 0);
  m_startFrameFld     = new DVGui::IntLineEdit(this, offset);

  // Whether the column color filter and transparency is available also in
  // render
  m_colorFilterOnRenderCB = new DVGui::CheckBox(
      tr("Enable Column Color Filter and Transparency for Rendering"), this);
  m_colorFilterOnRenderCB->setChecked(
      sprop->isColumnColorFilterOnRenderEnabled());

  QPushButton *editCellMarksButton =
      new QPushButton(tr("Edit Cell Marks"), this);

  // layout
  QGridLayout *mainLayout = new QGridLayout();
  mainLayout->setMargin(10);
  mainLayout->setHorizontalSpacing(5);
  mainLayout->setVerticalSpacing(15);
  {
    // Frame Rate
    mainLayout->addWidget(new QLabel(tr("Frame Rate:"), this), 0, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_frameRateFld, 0, 1, 1, 4,
                          Qt::AlignLeft | Qt::AlignVCenter);
    // Camera BG color
    mainLayout->addWidget(new QLabel(tr("Camera BG Color:"), this), 1, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_bgColorFld, 1, 1, 1, 4);
    // Field Guide Size - A/R
    mainLayout->addWidget(new QLabel(tr("Field Guide Size:"), this), 2, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_fieldGuideFld, 2, 1);
    mainLayout->addWidget(new QLabel(tr("A/R:"), this), 2, 2,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_aspectRatioFld, 2, 3, 1, 2,
                          Qt::AlignLeft | Qt::AlignVCenter);
    // Image Subsampling  - Tlv Subsampling
    mainLayout->addWidget(new QLabel(tr("Image Subsampling:"), this), 3, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_fullcolorSubsamplingFld, 3, 1);
    if (m_tlvSubsamplingFld) {
      mainLayout->addWidget(new QLabel(tr("TLV Subsampling:"), this), 4, 0,
                            Qt::AlignRight | Qt::AlignVCenter);
      mainLayout->addWidget(m_tlvSubsamplingFld, 4, 1);
    }
    // Marker Interval - Start Frame
    mainLayout->addWidget(new QLabel(tr("Marker Interval:"), this), 5, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_markerIntervalFld, 5, 1);
    mainLayout->addWidget(new QLabel(tr("  Start Frame:"), this), 5, 2,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(m_startFrameFld, 5, 3);

    // Use Color Filter and Transparency for Rendering
    mainLayout->addWidget(m_colorFilterOnRenderCB, 6, 0, 1, 4);

    // cell marks
    mainLayout->addWidget(new QLabel(tr("Cell Marks:"), this), 7, 0,
                          Qt::AlignRight | Qt::AlignVCenter);
    mainLayout->addWidget(editCellMarksButton, 7, 1, 1, 4,
                          Qt::AlignLeft | Qt::AlignVCenter);
  }
  mainLayout->setColumnStretch(0, 0);
  mainLayout->setColumnStretch(1, 0);
  mainLayout->setColumnStretch(2, 0);
  mainLayout->setColumnStretch(3, 0);
  mainLayout->setColumnStretch(4, 1);
  mainLayout->setRowStretch(9, 1);
  setLayout(mainLayout);

  // signal-slot connections
  bool ret = true;
  // Frame Rate
  ret = ret && connect(m_frameRateFld, SIGNAL(editingFinished()), this,
                       SLOT(onFrameRateEditingFinished()));
  // Camera BG color
  ret =
      ret && connect(m_bgColorFld, SIGNAL(colorChanged(const TPixel32 &, bool)),
                     this, SLOT(setBgColor(const TPixel32 &, bool)));
  // Field Guide Size - A/R
  ret = ret && connect(m_fieldGuideFld, SIGNAL(editingFinished()), this,
                       SLOT(onFieldGuideSizeEditingFinished()));
  ret = ret && connect(m_aspectRatioFld, SIGNAL(editingFinished()), this,
                       SLOT(onFieldGuideAspectRatioEditingFinished()));
  // Image Subsampling  - Tlv Subsampling
  ret = ret && connect(m_fullcolorSubsamplingFld, SIGNAL(editingFinished()),
                       this, SLOT(onFullColorSubsampEditingFinished()));
  if (m_tlvSubsamplingFld)
    ret = ret && connect(m_tlvSubsamplingFld, SIGNAL(editingFinished()), this,
                         SLOT(onTlvSubsampEditingFinished()));
  // Marker Interval - Start Frame
  ret = ret && connect(m_markerIntervalFld, SIGNAL(editingFinished()), this,
                       SLOT(onMakerInformationChanged()));
  ret = ret && connect(m_startFrameFld, SIGNAL(editingFinished()), this,
                       SLOT(onMakerInformationChanged()));

  // Use Color Filter and Transparency for Rendering
  ret = ret && connect(m_colorFilterOnRenderCB, SIGNAL(stateChanged(int)), this,
                       SLOT(onColorFilterOnRenderChanged()));
  // Cell Marks
  ret = ret && connect(editCellMarksButton, SIGNAL(clicked()), this,
                       SLOT(onEditCellMarksButtonClicked()));
  assert(ret);
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::showEvent(QShowEvent *e) {
  TSceneHandle *sceneHandle = TApp::instance()->getCurrentScene();
  connect(sceneHandle, SIGNAL(sceneChanged()), SLOT(update()));
  connect(sceneHandle, SIGNAL(sceneSwitched()), SLOT(update()));

  update();
}

void SceneSettingsPopup::hideEvent(QHideEvent *e) {
  TSceneHandle *sceneHandle = TApp::instance()->getCurrentScene();
  disconnect(sceneHandle, SIGNAL(sceneChanged()), this, SLOT(update()));
  disconnect(sceneHandle, SIGNAL(sceneSwitched()), this, SLOT(update()));
}

//-----------------------------------------------------------------------------

TSceneProperties *SceneSettingsPopup::getProperties() const {
  return TApp::instance()->getCurrentScene()->getScene()->getProperties();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::update() {
  TSceneProperties *sprop = getProperties();

  QString str;
  m_frameRateFld->setValue(sprop->getOutputProperties()->getFrameRate());

  TPixel32 col1, col2;
  Preferences::instance()->getChessboardColors(col1, col2);
  m_bgColorFld->setChessboardColors(col1, col2);

  TPixel bgColor = sprop->getBgColor();
  m_bgColorFld->setColor(bgColor);

  m_fieldGuideFld->setValue(sprop->getFieldGuideSize());
  m_aspectRatioFld->setValue(sprop->getFieldGuideAspectRatio());

  UnitParameters::setFieldGuideAspectRatio(sprop->getFieldGuideAspectRatio());
  m_fullcolorSubsamplingFld->setValue(sprop->getFullcolorSubsampling());
  if (m_tlvSubsamplingFld)
    m_tlvSubsamplingFld->setValue(sprop->getTlvSubsampling());
  int markerDistance = 0, markerOffset = 0, secDistance;
  sprop->getMarkers(markerDistance, markerOffset, secDistance);
  m_markerIntervalFld->setValue(markerDistance);
  m_startFrameFld->setValue(markerOffset + 1);
  m_colorFilterOnRenderCB->setChecked(
      sprop->isColumnColorFilterOnRenderEnabled());

  if (m_cellMarksPopup) m_cellMarksPopup->update();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onFrameRateEditingFinished() {
  TSceneProperties *sprop  = getProperties();
  double frameRate         = sprop->getOutputProperties()->getFrameRate();
  double frameRateFldValue = m_frameRateFld->getValue();
  if (frameRate == frameRateFldValue) return;
  sprop->getOutputProperties()->setFrameRate(frameRateFldValue);
  TApp::instance()->getCurrentScene()->getScene()->updateSoundColumnFrameRate();
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->getXsheet()->updateFrameCount();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onFieldGuideSizeEditingFinished() {
  TSceneProperties *sprop = getProperties();
  int fieldGuideSize      = sprop->getFieldGuideSize();
  int fieldGuideSizefld   = m_fieldGuideFld->text().toInt();
  if (fieldGuideSize == fieldGuideSizefld) return;
  sprop->setFieldGuideSize(fieldGuideSizefld);
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onFieldGuideAspectRatioEditingFinished() {
  TSceneProperties *sprop      = getProperties();
  double fieldGuideAspectRatio = sprop->getFieldGuideAspectRatio();
  double aspectRatioFld        = m_aspectRatioFld->text().toDouble();
  if (fieldGuideAspectRatio == aspectRatioFld) return;
  sprop->setFieldGuideAspectRatio(aspectRatioFld);
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
  UnitParameters::setFieldGuideAspectRatio(m_aspectRatioFld->text().toDouble());
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onFullColorSubsampEditingFinished() {
  TSceneProperties *sprop     = getProperties();
  int fullcolorSubsampling    = sprop->getFullcolorSubsampling();
  int fullcolorSubsamplingFld = m_fullcolorSubsamplingFld->getValue();
  if (fullcolorSubsampling == fullcolorSubsamplingFld) return;
  sprop->setFullcolorSubsampling(fullcolorSubsamplingFld);
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onTlvSubsampEditingFinished() {
  if (!m_tlvSubsamplingFld) return;
  TSceneProperties *sprop = getProperties();
  int tlvSubsampling      = sprop->getTlvSubsampling();
  int tlvSubsamplingFld   = m_tlvSubsamplingFld->getValue();
  if (tlvSubsamplingFld == tlvSubsampling) return;
  sprop->setTlvSubsampling(tlvSubsamplingFld);
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onMakerInformationChanged() {
  TSceneProperties *sprop = getProperties();
  int distance, offset, secDistance;
  sprop->getMarkers(distance, offset, secDistance);
  int markerDistance = m_markerIntervalFld->text().toInt();
  int markerOffset   = m_startFrameFld->text().toInt() - 1;

  if (distance == markerDistance && offset == markerOffset) return;
  sprop->setMarkers(markerDistance, markerOffset);
  TApp::instance()->getCurrentScene()->notifySceneChanged();
  TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::setBgColor(const TPixel32 &bgColor, bool isDragging) {
  TSceneProperties *sprop = getProperties();
  sprop->setBgColor(bgColor);
  // TODO: forse sarebbe meglio usare una notifica piu' specifica
  if (!isDragging) Previewer::clearAll();
  TApp::instance()->getCurrentScene()->notifySceneChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onColorFilterOnRenderChanged() {
  TSceneProperties *sprop = getProperties();
  sprop->enableColumnColorFilterOnRender(m_colorFilterOnRenderCB->isChecked());
  TApp::instance()->getCurrentScene()->notifySceneChanged();
}

//-----------------------------------------------------------------------------

void SceneSettingsPopup::onEditCellMarksButtonClicked() {
  if (!m_cellMarksPopup) m_cellMarksPopup = new CellMarksPopup(this);
  m_cellMarksPopup->show();
  m_cellMarksPopup->raise();
}

//=============================================================================

OpenPopupCommandHandler<SceneSettingsPopup> openSceneSettingsPopup(
    MI_SceneSettings);