Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qmouseevent></qmouseevent>
Toshihiro Shimizu 890ddd
#include <qpaintevent></qpaintevent>
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/marksbar.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace stuff
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void crop(QVector<int> &values, int min, int max) {</int>
Shinya Kitaoka 120a6e
  QVector<int>::iterator it, end = values.end();</int>
Shinya Kitaoka 120a6e
  for (it = values.begin(); it != end; ++it) *it = tcrop(*it, min, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void rollDown(QVector<int> &values, int max, int sortDist) {</int>
Shinya Kitaoka 120a6e
  assert(!values.empty());
Shinya Kitaoka 120a6e
  values.back() = std::min(max, values.back());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QVector<int>::iterator it, jt, beg = values.begin();</int>
Shinya Kitaoka 120a6e
  for (it = values.end(), jt = --it; jt != beg; jt = it) {
Shinya Kitaoka 120a6e
    --it;
Shinya Kitaoka 120a6e
    val                = *jt - sortDist;
Shinya Kitaoka 120a6e
    if (*it > val) *it = val;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void rollUp(QVector<int> &values, int min, int sortDist) {</int>
Shinya Kitaoka 120a6e
  assert(!values.empty());
Shinya Kitaoka 120a6e
  values.front() = std::max(min, values.front());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QVector<int>::iterator it, jt, end = values.end();</int>
Shinya Kitaoka 120a6e
  for (jt = values.begin(), it = jt++; jt != end; it = jt, ++jt) {
Shinya Kitaoka 120a6e
    val                = *it + sortDist;
Shinya Kitaoka 120a6e
    if (val > *jt) *jt = val;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
//    MarksBar implementation
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MarksBar::MarksBar(QWidget *parent, bool markUp)
Shinya Kitaoka 120a6e
    : QFrame(parent)
Shinya Kitaoka 120a6e
    , m_markUp(markUp)
Shinya Kitaoka 120a6e
    , m_min(0)
Shinya Kitaoka 120a6e
    , m_max(100)
Shinya Kitaoka 120a6e
    , m_sortDist(-1)
Shinya Kitaoka 120a6e
    , m_selectedMark(-1) {
Shinya Kitaoka 120a6e
  setMinimumWidth(100);
Shinya Kitaoka 120a6e
  setFixedHeight(6);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::setRange(int min, int max, int sortDist) {
Shinya Kitaoka 120a6e
  assert(min <= max);
Shinya Kitaoka 120a6e
  m_min = min, m_max = max, m_sortDist = sortDist;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  conformValues();
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int MarksBar::valToPos(int val) {
Shinya Kitaoka 120a6e
  const QRect contsRect = contentsRect();
Shinya Kitaoka 120a6e
  return contsRect.left() +
Shinya Kitaoka 120a6e
         contsRect.width() * ((val - m_min) / (double)(m_max - m_min));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int MarksBar::posToVal(int pos) {
Shinya Kitaoka 120a6e
  const QRect contsRect = contentsRect();
Shinya Kitaoka 120a6e
  return m_min +
Shinya Kitaoka 120a6e
         (m_max - m_min) *
Shinya Kitaoka 120a6e
             ((pos - contsRect.left()) / (double)contsRect.width());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::conformValues(bool preferRollDown) {
Shinya Kitaoka 120a6e
  if (m_values.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_sortDist < 0)
Shinya Kitaoka 120a6e
    ::crop(m_values, m_min, m_max);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    if (preferRollDown) {
Shinya Kitaoka 120a6e
      ::rollDown(m_values, m_max, m_sortDist);
Shinya Kitaoka 120a6e
      ::rollUp(m_values, m_min, m_sortDist);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      ::rollUp(m_values, m_min, m_sortDist);
Shinya Kitaoka 120a6e
      ::rollDown(m_values, m_max, m_sortDist);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  update();
Shinya Kitaoka 120a6e
  emit marksUpdated();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::mousePressEvent(QMouseEvent *me) {
Shinya Kitaoka 120a6e
  int newDist, currDist = (std::numeric_limits<int>::max)();</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int val = posToVal(me->x());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Select the nearest mark. If the distance is too great, select none.
Shinya Kitaoka 120a6e
  int i, size = m_values.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) {
Shinya Kitaoka 120a6e
    newDist = abs(m_values[i] - val);
Shinya Kitaoka 120a6e
    if (newDist < 7 && newDist < currDist) m_selectedMark = i;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::mouseMoveEvent(QMouseEvent *me) {
Shinya Kitaoka 120a6e
  if (m_selectedMark < 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int newVal = tcrop(posToVal(me->x()), m_min, m_max);
Shinya Kitaoka 120a6e
  bool left  = newVal < m_values[m_selectedMark];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_values[m_selectedMark] = newVal;
Shinya Kitaoka 120a6e
  conformValues(left);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::mouseReleaseEvent(QMouseEvent *me) {
Shinya Kitaoka 120a6e
  m_selectedMark = -1;
Shinya Kitaoka 120a6e
  emit marksReleased();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::drawMark(QPainter &p, int pos, const QColor &color) {
Shinya Kitaoka 120a6e
  QPolygon poly(3);
Shinya Kitaoka 120a6e
  if (m_markUp) {
Shinya Kitaoka 120a6e
    poly[0] = QPoint(pos - 5, 5);
Shinya Kitaoka 120a6e
    poly[1] = QPoint(pos + 5, 5);
Shinya Kitaoka 120a6e
    poly[2] = QPoint(pos, 0);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    poly[0] = QPoint(pos - 5, 0);
Shinya Kitaoka 120a6e
    poly[1] = QPoint(pos + 5, 0);
Shinya Kitaoka 120a6e
    poly[2] = QPoint(pos, 5);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p.setBrush(color);
Shinya Kitaoka 120a6e
  p.drawPolygon(poly);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MarksBar::paintEvent(QPaintEvent *pe) {
Shinya Kitaoka 120a6e
  QPainter p(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_values.size() == m_colors.size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Draw markers
Shinya Kitaoka 120a6e
  int i, size = m_values.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) drawMark(p, valToPos(m_values[i]), m_colors[i]);
Toshihiro Shimizu 890ddd
}