#include "toonzqt/intfield.h" #include "toonzqt/dvdialog.h" #include "toonzqt/gutil.h" #include #include #include #include #include #include using namespace DVGui; //============================================================================= // RollerField //----------------------------------------------------------------------------- RollerField::RollerField(QWidget *parent) : QWidget(parent), m_value(0), m_minValue(-100000.0), m_maxValue(100000.0), m_xPos(0), m_step(1.0) { setMinimumSize(43, 7); } //----------------------------------------------------------------------------- void RollerField::setValue(double value) { if (m_value == value) return; if (value < m_minValue) m_value = m_minValue; if (value > m_maxValue) m_value = m_maxValue; m_value = value; } //----------------------------------------------------------------------------- double RollerField::getValue() const { return m_value; } //----------------------------------------------------------------------------- void RollerField::setRange(double minValue, double maxValue) { m_minValue = minValue; m_maxValue = maxValue; } //----------------------------------------------------------------------------- void RollerField::getRange(double &minValue, double &maxValue) { minValue = m_minValue; maxValue = m_maxValue; } //----------------------------------------------------------------------------- void RollerField::paintEvent(QPaintEvent *e) { QPainter p(this); int w = width(); drawArrow(p, QPointF(3, 3), QPointF(5, 5), QPointF(5, 1), true, Qt::black, Qt::black); drawArrow(p, QPointF(w - 4, 3), QPointF(w - 6, 5), QPointF(w - 6, 1), true, Qt::black, Qt::black); p.drawLine(QPoint(3, 3), QPoint(w - 4, 3)); } //----------------------------------------------------------------------------- void RollerField::mousePressEvent(QMouseEvent *e) { if (e->buttons() == Qt::LeftButton) { m_xPos = e->pos().x(); e->accept(); } } //----------------------------------------------------------------------------- void RollerField::mouseMoveEvent(QMouseEvent *e) { if (e->buttons() == Qt::LeftButton) { if (m_xPos < e->pos().x()) addValue(true); else if (m_xPos > e->pos().x()) removeValue(true); m_xPos = e->pos().x(); e->accept(); } } //----------------------------------------------------------------------------- void RollerField::mouseReleaseEvent(QMouseEvent *e) { e->accept(); emit valueChanged(false); } //----------------------------------------------------------------------------- void RollerField::addValue(bool isDragging) { double newValue = tcrop(m_value + m_step, m_minValue, m_maxValue); if (newValue == m_value) return; m_value = newValue; emit valueChanged(isDragging); } //----------------------------------------------------------------------------- void RollerField::removeValue(bool isDragging) { double newValue = tcrop(m_value - m_step, m_minValue, m_maxValue); if (newValue == m_value) return; m_value = newValue; emit valueChanged(isDragging); } //============================================================================= // IntLineEdit //----------------------------------------------------------------------------- IntLineEdit::IntLineEdit(QWidget *parent, int value, int minValue, int maxValue, int showedDigits) : LineEdit(parent), m_showedDigits(showedDigits) { setFixedWidth(54); m_validator = new QIntValidator(this); setValue(value); setRange(minValue, maxValue); setValidator(m_validator); } //----------------------------------------------------------------------------- void IntLineEdit::setValue(int value) { int minValue, maxValue; getRange(minValue, maxValue); if (value < minValue) value = minValue; if (value > maxValue) value = maxValue; QString str; str.setNum(value); if (m_showedDigits > 0) { while (str.length() < m_showedDigits) str.push_front("0"); while (str.length() > m_showedDigits) str.remove(0, 1); } setText(str); //Faccio in modo che il cursore sia sulla prima cifra, cosi' se la stringa da visualizzare //e' piu' lunga del campo le cifre che vengono troncate sono le ultime e non le prime. setCursorPosition(0); } //----------------------------------------------------------------------------- int IntLineEdit::getValue() { return text().toInt(); } //----------------------------------------------------------------------------- void IntLineEdit::setRange(int minValue, int maxValue) { m_validator->setRange(minValue, maxValue); } //----------------------------------------------------------------------------- void IntLineEdit::getRange(int &minValue, int &maxValue) { minValue = m_validator->bottom(); maxValue = m_validator->top(); } //----------------------------------------------------------------------------- void IntLineEdit::setBottomRange(int minValue) { m_validator->setBottom(minValue); } //----------------------------------------------------------------------------- void IntLineEdit::setTopRange(int maxValue) { m_validator->setTop(maxValue); } //----------------------------------------------------------------------------- void IntLineEdit::focusOutEvent(QFocusEvent *e) { int value = getValue(); int minValue, maxValue; getRange(minValue, maxValue); if (e->lostFocus()) setValue(value); QLineEdit::focusOutEvent(e); } //----------------------------------------------------------------------------- // for fps edit in flip console void IntLineEdit::setLineEditBackgroundColor(QColor color) { QString sheet = QString("background-color: rgb(") + QString::number(color.red()) + QString(",") + QString::number(color.green()) + QString(",") + QString::number(color.blue()) + QString(",") + QString::number(color.alpha()) + QString(");"); setStyleSheet(sheet); } //============================================================================= // IntField //----------------------------------------------------------------------------- IntField::IntField(QWidget *parent, bool isMaxRangeLimited, bool isRollerHide) : QWidget(parent), m_lineEdit(0), m_slider(0), m_roller(0), m_isMaxRangeLimited(isMaxRangeLimited) { setObjectName("IntField"); QHBoxLayout *layout = new QHBoxLayout(this); layout->setMargin(0); layout->setSpacing(5); QWidget *field = new QWidget(this); field->setMaximumWidth(43); QVBoxLayout *vLayout = new QVBoxLayout(field); vLayout->setMargin(0); vLayout->setSpacing(0); m_lineEdit = new DVGui::IntLineEdit(field); bool ret = connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(onEditingFinished())); vLayout->addWidget(m_lineEdit); m_roller = new RollerField(field); ret = ret && connect(m_roller, SIGNAL(valueChanged(bool)), this, SLOT(onRollerValueChanged(bool))); vLayout->addWidget(m_roller); if (isRollerHide) enableRoller(false); layout->addWidget(field); m_slider = new QSlider(Qt::Horizontal, this); ret = ret && connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderChanged(int))); ret = ret && connect(m_slider, SIGNAL(sliderReleased()), this, SLOT(onSliderReleased())); ret = ret && connect(m_lineEdit, SIGNAL(editingFinished()), this, SIGNAL(valueEditedByHand())); ret = ret && connect(m_slider, SIGNAL(sliderReleased()), this, SIGNAL(valueEditedByHand())); layout->addWidget(m_slider); setValues(0, 0, 100); setLayout(layout); assert(ret); } //----------------------------------------------------------------------------- void IntField::getRange(int &minValue, int &maxValue) { double min, max; m_roller->getRange(min, max); minValue = tround(min); maxValue = tround(max); } //----------------------------------------------------------------------------- void IntField::setRange(int minValue, int maxValue) { m_lineEdit->setRange(minValue, m_isMaxRangeLimited ? maxValue : (std::numeric_limits::max)()); m_slider->setRange(minValue, maxValue); m_roller->setRange(minValue, maxValue); } //----------------------------------------------------------------------------- void IntField::setValue(int value) { if (m_lineEdit->getValue() == value) return; m_lineEdit->setValue(value); m_slider->setSliderPosition(value); m_roller->setValue((double)value); } //----------------------------------------------------------------------------- int IntField::getValue() { return (m_lineEdit->getValue()); } //----------------------------------------------------------------------------- void IntField::setValues(int value, int minValue, int maxValue) { setRange(minValue, maxValue); setValue(value); } //----------------------------------------------------------------------------- void IntField::enableSlider(bool enable) { m_slider->setEnabled(enable); if (enable) m_slider->show(); else m_slider->hide(); } //----------------------------------------------------------------------------- bool IntField::sliderIsEnabled() { return m_slider->isEnabled(); } //----------------------------------------------------------------------------- void IntField::enableRoller(bool enable) { m_roller->setEnabled(enable); if (enable) m_roller->show(); else m_roller->hide(); } //----------------------------------------------------------------------------- bool IntField::rollerIsEnabled() { return m_roller->isEnabled(); } //----------------------------------------------------------------------------- void IntField::setLineEditBackgroundColor(QColor color) { m_lineEdit->setLineEditBackgroundColor(color); } //----------------------------------------------------------------------------- void IntField::onSliderChanged(int value) { //Controllo necessario per evitare che il segnale di cambiamento venga emesso piu' volte. if (m_lineEdit->getValue() == value || ((int)m_roller->getValue() == value && m_roller->isVisible())) return; m_lineEdit->setValue(value); m_roller->setValue((double)value); //Faccio in modo che il cursore sia sulla prima cifra, cosi' se la stringa //da visualizzare e' piu' lunga del campo le cifre che vengono troncate sono //le ultime e non le prime (dovrebbero essere quelle dopo la virgola). m_lineEdit->setCursorPosition(0); emit valueChanged(true); } //----------------------------------------------------------------------------- void IntField::onEditingFinished() { double value = m_lineEdit->getValue(); //Controllo necessario per evitare che il segnale di cambiamento venga emesso piu' volte. if ((m_slider->value() == value && m_slider->isVisible()) || (int)m_roller->getValue() == value && m_roller->isVisible()) return; m_slider->setValue(value); m_roller->setValue((double)value); emit valueChanged(false); } //----------------------------------------------------------------------------- void IntField::onRollerValueChanged(bool isDragging) { int value = m_roller->getValue(); if (value == m_lineEdit->getValue()) { assert(m_slider->value() == value || !m_slider->isVisible()); // Se isDragging e' falso e' giusto che venga emessa la notifica di cambiamento. if (!isDragging) emit valueChanged(isDragging); return; } m_slider->setValue(value); m_lineEdit->setValue(value); //Faccio in modo che il cursore sia sulla prima cifra, cosi' se la stringa //da visualizzare e' piu' lunga del campo le cifre che vengono troncate sono //le ultime e non le prime (dovrebbero essere quelle dopo la virgola). m_lineEdit->setCursorPosition(0); emit valueChanged(isDragging); }