Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/columnfan.h"
John Dancel 421acd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includss
Toshihiro Shimizu 890ddd
#include <assert.h></assert.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Jaroslav 203cc8
// ColumnFan
Toshihiro Shimizu 890ddd
John Dancel 421acd
ColumnFan::ColumnFan()
shun-iwasawa 52004d
    : m_firstFreePos(0)
shun-iwasawa 52004d
    , m_unfolded(74)
shun-iwasawa 52004d
    , m_folded(9)
shun-iwasawa 52004d
    , m_cameraActive(true)
shun-iwasawa 52004d
    , m_cameraColumnDim(22) {}
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 52004d
void ColumnFan::setDimensions(int unfolded, int cameraColumn) {
shun-iwasawa 52004d
  m_unfolded        = unfolded;
shun-iwasawa 52004d
  m_cameraColumnDim = cameraColumn;
Jaroslav 203cc8
  // folded always 9
Jaroslav 203cc8
  update();
Jaroslav 203cc8
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ColumnFan::update() {
Jaroslav 203cc8
  int lastPos     = -m_unfolded;
Shinya Kitaoka 120a6e
  bool lastActive = true;
Shinya Kitaoka 120a6e
  int m           = m_columns.size();
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m; i++) {
Shinya Kitaoka 120a6e
    bool active = m_columns[i].m_active;
Shinya Kitaoka 120a6e
    if (lastActive)
Jaroslav 203cc8
      lastPos += m_unfolded;
Shinya Kitaoka 120a6e
    else if (active)
Jaroslav 203cc8
      lastPos += m_folded;
Shinya Kitaoka 120a6e
    m_columns[i].m_pos = lastPos;
Shinya Kitaoka 120a6e
    lastActive         = active;
Shinya Kitaoka 120a6e
  }
Jaroslav 203cc8
  m_firstFreePos = lastPos + (lastActive ? m_unfolded : m_folded);
Shinya Kitaoka 120a6e
  m_table.clear();
Shinya Kitaoka 120a6e
  for (i = 0; i < m; i++)
Shinya Kitaoka 120a6e
    if (m_columns[i].m_active)
Jaroslav 203cc8
      m_table[m_columns[i].m_pos + m_unfolded - 1] = i;
Shinya Kitaoka 120a6e
    else if (i + 1 < m && m_columns[i + 1].m_active)
Shinya Kitaoka 120a6e
      m_table[m_columns[i + 1].m_pos - 1] = i;
Shinya Kitaoka 120a6e
    else if (i + 1 == m)
Shinya Kitaoka 120a6e
      m_table[m_firstFreePos - 1] = i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
int ColumnFan::layerAxisToCol(int coord) const {
manongjohn 3fe913
  if (Preferences::instance()->isXsheetCameraColumnVisible()) {
John Dancel 421acd
    int firstCol =
John Dancel 421acd
        m_cameraActive
shun-iwasawa 52004d
            ? m_cameraColumnDim
John Dancel 421acd
            : ((m_columns.size() > 0 && !m_columns[0].m_active) ? 0 : m_folded);
John Dancel 421acd
    if (coord < firstCol) return -1;
John Dancel 421acd
    coord -= firstCol;
John Dancel 421acd
  }
Jaroslav 203cc8
  if (coord < m_firstFreePos) {
Jaroslav 203cc8
    std::map<int, int="">::const_iterator it = m_table.lower_bound(coord);</int,>
Shinya Kitaoka 120a6e
    if (it == m_table.end()) return -3;
Shinya Kitaoka 120a6e
    assert(it != m_table.end());
Shinya Kitaoka 120a6e
    return it->second;
Shinya Kitaoka 120a6e
  } else
Jaroslav 203cc8
    return m_columns.size() + (coord - m_firstFreePos) / m_unfolded;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
int ColumnFan::colToLayerAxis(int col) const {
John Dancel 421acd
  int m        = m_columns.size();
John Dancel 421acd
  int firstCol = 0;
manongjohn 3fe913
  if (Preferences::instance()->isXsheetCameraColumnVisible()) {
shun-iwasawa 52004d
    if (col < -1) return -m_cameraColumnDim;
John Dancel 421acd
    if (col < 0) return 0;
John Dancel 421acd
    firstCol =
John Dancel 421acd
        m_cameraActive
shun-iwasawa 52004d
            ? m_cameraColumnDim
John Dancel 421acd
            : ((m_columns.size() > 0 && !m_columns[0].m_active) ? 0 : m_folded);
John Dancel 421acd
  }
Shinya Kitaoka 120a6e
  if (col >= 0 && col < m)
John Dancel 421acd
    return firstCol + m_columns[col].m_pos;
Shinya Kitaoka 120a6e
  else
John Dancel 421acd
    return firstCol + m_firstFreePos + (col - m) * m_unfolded;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ColumnFan::activate(int col) {
Shinya Kitaoka 120a6e
  int m = m_columns.size();
John Dancel 421acd
  if (col < 0) {
John Dancel 421acd
    m_cameraActive = true;
John Dancel 421acd
    return;
John Dancel 421acd
  }
Shinya Kitaoka 120a6e
  if (col < m) {
Shinya Kitaoka 120a6e
    m_columns[col].m_active = true;
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = m - 1; i >= 0 && m_columns[i].m_active; i--) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    i++;
Shinya Kitaoka 120a6e
    if (i < m) {
Shinya Kitaoka 120a6e
      m = i;
Shinya Kitaoka 120a6e
      m_columns.erase(m_columns.begin() + i, m_columns.end());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ColumnFan::deactivate(int col) {
John Dancel 421acd
  if (col < 0) {
John Dancel 421acd
    m_cameraActive = false;
John Dancel 421acd
    return;
John Dancel 421acd
  }
Shinya Kitaoka 120a6e
  while ((int)m_columns.size() <= col) m_columns.push_back(Column());
Shinya Kitaoka 120a6e
  m_columns[col].m_active = false;
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ColumnFan::isActive(int col) const {
John Dancel 421acd
  return 0 <= col && col < (int)m_columns.size()
John Dancel 421acd
             ? m_columns[col].m_active
John Dancel 421acd
             : col < 0 ? m_cameraActive : true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool ColumnFan::isEmpty() const { return m_columns.empty(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
void ColumnFan::copyFoldedStateFrom(const ColumnFan &from) {
John Dancel 421acd
  m_cameraActive = from.m_cameraActive;
Jaroslav 203cc8
  for (int i = 0, n = (int)from.m_columns.size(); i < n; i++)
Jaroslav 203cc8
    if (!from.isActive(i)) deactivate(i);
Jaroslav 203cc8
}
Jaroslav 203cc8
Jaroslav 203cc8
//-----------------------------------------------------------------------------
Jaroslav 203cc8
Jaroslav 203cc8
void ColumnFan::saveData(
Jaroslav 203cc8
    TOStream &os) {  // only saves indices of folded columns
Shinya Kitaoka 120a6e
  int index, n = (int)m_columns.size();
Shinya Kitaoka 120a6e
  for (index = 0; index < n;) {
Shinya Kitaoka 120a6e
    while (index < n && m_columns[index].m_active) index++;
Shinya Kitaoka 120a6e
    if (index < n) {
Shinya Kitaoka 120a6e
      int firstIndex = index;
Shinya Kitaoka 120a6e
      os << index;
Shinya Kitaoka 120a6e
      index++;
Shinya Kitaoka 120a6e
      while (index < n && !m_columns[index].m_active) index++;
Shinya Kitaoka 120a6e
      os << index - firstIndex;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ColumnFan::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  m_columns.clear();
Shinya Kitaoka 120a6e
  m_table.clear();
Shinya Kitaoka 120a6e
  m_firstFreePos = 0;
Shinya Kitaoka 120a6e
  while (!is.eos()) {
Shinya Kitaoka 120a6e
    int index = 0, count = 0;
Shinya Kitaoka 120a6e
    is >> index >> count;
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = 0; j < count; j++) deactivate(index + j);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun-iwasawa 98258e
shun-iwasawa 98258e
//-----------------------------------------------------------------------------
shun-iwasawa 98258e
shun-iwasawa 98258e
void ColumnFan::rollLeftFoldedState(int index, int count) {
shun-iwasawa 98258e
  assert(index >= 0);
shun-iwasawa 98258e
  int columnCount = m_columns.size();
shun-iwasawa 98258e
  if (columnCount <= index) return;
shun-iwasawa 98258e
  if (index + count - 1 > columnCount) count = columnCount - index + 1;
shun-iwasawa 98258e
  if (count < 2) return;
shun-iwasawa 98258e
shun-iwasawa 98258e
  int i = index, j = index + count - 1;
shun-iwasawa 98258e
  bool tmp = isActive(i);
shun-iwasawa 98258e
shun-iwasawa 98258e
  for (int k = i; k < j; ++k) {
shun-iwasawa 98258e
    if (isActive(k) && !isActive(k + 1))
shun-iwasawa 98258e
      deactivate(k);
shun-iwasawa 98258e
    else if (!isActive(k) && isActive(k + 1))
shun-iwasawa 98258e
      activate(k);
shun-iwasawa 98258e
  }
shun-iwasawa 98258e
  if (isActive(j) && !tmp)
shun-iwasawa 98258e
    deactivate(j);
shun-iwasawa 98258e
  else if (!isActive(j) && tmp)
shun-iwasawa 98258e
    activate(j);
shun-iwasawa 98258e
shun-iwasawa 98258e
  update();
shun-iwasawa 98258e
}
shun-iwasawa 98258e
shun-iwasawa 98258e
//-----------------------------------------------------------------------------
shun-iwasawa 98258e
shun-iwasawa 98258e
void ColumnFan::rollRightFoldedState(int index, int count) {
shun-iwasawa 98258e
  assert(index >= 0);
shun-iwasawa 98258e
shun-iwasawa 98258e
  int columnCount = m_columns.size();
shun-iwasawa 98258e
  if (columnCount <= index) return;
shun-iwasawa 98258e
  if (index + count - 1 > columnCount) count = columnCount - index + 1;
shun-iwasawa 98258e
  if (count < 2) return;
shun-iwasawa 98258e
shun-iwasawa 98258e
  int i = index, j = index + count - 1;
shun-iwasawa 98258e
  bool tmp = isActive(j);
shun-iwasawa 98258e
shun-iwasawa 98258e
  for (int k = j; k > i; --k) {
shun-iwasawa 98258e
    if (isActive(k) && !isActive(k - 1))
shun-iwasawa 98258e
      deactivate(k);
shun-iwasawa 98258e
    else if (!isActive(k) && isActive(k - 1))
shun-iwasawa 98258e
      activate(k);
shun-iwasawa 98258e
  }
shun-iwasawa 98258e
  if (isActive(i) && !tmp)
shun-iwasawa 98258e
    deactivate(i);
shun-iwasawa 98258e
  else if (!isActive(i) && tmp)
shun-iwasawa 98258e
    activate(i);
shun-iwasawa 98258e
shun-iwasawa 98258e
  update();
shun-iwasawa 98258e
}