blob: 1e90428ba69ee59850a6687ae9e25c66a9ecebb5 [file] [log] [blame]
#include "android/skin/qt/editable-slider-widget.h"
#include <QEvent>
#include <QStyle>
EditableSliderWidget::EditableSliderWidget(QWidget *parent) :
QWidget(parent),
mMinValueLabel(this),
mMaxValueLabel(this),
mSlider(Qt::Horizontal, this),
mLineEdit(this),
mLineEditValidator(&mLineEdit) {
// Arrange the child widgets in a layout.
mSliderLabelsLayout.setSpacing(0);
mSliderLabelsLayout.addWidget(&mMinValueLabel);
mSliderLabelsLayout.addWidget(&mMaxValueLabel);
mAnnotatedSliderLayout.setSpacing(0);
mAnnotatedSliderLayout.addWidget(&mSlider);
mAnnotatedSliderLayout.addSpacing(3);
mAnnotatedSliderLayout.addLayout(&mSliderLabelsLayout);
mEditBoxLayout.setSpacing(0);
mEditBoxLayout.addWidget(&mLineEdit);
mEditBoxLayout.addStretch();
mMainLayout.setSpacing(0);
mMainLayout.addLayout(&mAnnotatedSliderLayout);
mMainLayout.addSpacing(16);
mMainLayout.addLayout(&mEditBoxLayout);
setLayout(&mMainLayout);
// Set initial values.
setMinimum(static_cast<int>(mSlider.minimum()/10.0));
setMaximum(static_cast<int>(mSlider.maximum()/10.0));
setValue(static_cast<int>(mSlider.value()/10.0));
// Do some adjustments to child widgets.
mMinValueLabel.setAlignment(Qt::AlignLeft | Qt::AlignTop);
mMaxValueLabel.setAlignment(Qt::AlignRight | Qt::AlignTop);
mMinValueLabel.setProperty("ColorGroup", "SliderLabel");
mMaxValueLabel.setProperty("ColorGroup", "SliderLabel");
mLineEditValidator.setDecimals(1);
mLineEditValidator.setNotation(QDoubleValidator::StandardNotation);
mLineEditValidator.setLocale(QLocale::c());
mLineEdit.setValidator(&mLineEditValidator);
mLineEdit.setAlignment(Qt::AlignRight | Qt::AlignTop);
mLineEdit.setMaximumWidth(60);
mLineEdit.setTextMargins(0, 0, 0, 4);
mLineEdit.setProperty("class", "EditableValue");
mLineEdit.installEventFilter(this);
// Handle child widgets' value changes in our own slots.
connect(&mSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
connect(&mSlider, SIGNAL(sliderPressed()), this, SIGNAL(sliderPressed()));
connect(&mSlider, SIGNAL(sliderReleased()), this, SIGNAL(sliderReleased()));
connect(&mLineEdit, SIGNAL(editingFinished()), this, SLOT(lineEditValueChanged()));
}
void EditableSliderWidget::setValue(double value, bool emit_signal) {
// Clip the value to the allowed range.
mValue =
value < mMinimum ? mMinimum : (value > mMaximum ? mMaximum : value);
// Update the values displayed by the slider and the edit box.
{
QSignalBlocker blocker(mSlider);
mSlider.setValue(static_cast<int>(mValue * 10.0));
}
mLineEdit.setText(QString("%1").arg(mValue, 0, 'f', 1, '0'));
if (emit_signal) {
emit valueChanged(mValue);
emit valueChanged();
}
mLineEdit.setProperty("ColorGroup", QString());
mLineEdit.style()->unpolish(&mLineEdit);
mLineEdit.style()->polish(&mLineEdit);
}
void EditableSliderWidget::setMinimum(double minimum) {
mMinimum = minimum;
mLineEditValidator.setBottom(mMinimum);
setValue(mValue); // Force the current value into the new bounds.
mMinValueLabel.setText(QString::number(mMinimum));
mSlider.setMinimum(static_cast<int>(mMinimum * 10.0));
}
void EditableSliderWidget::setMaximum(double maximum) {
mMaximum = maximum;
mLineEditValidator.setTop(mMaximum);
setValue(mValue); // Force the current value into the new bounds.
mMaxValueLabel.setText(QString::number(mMaximum));
mSlider.setMaximum(static_cast<int>(mMaximum * 10.0));
}
void EditableSliderWidget::sliderValueChanged(int new_value) {
setValue(static_cast<double>(new_value) / 10.0);
}
void EditableSliderWidget::lineEditValueChanged() {
QString new_value = mLineEdit.text();
setValue(new_value.toDouble());
}
bool EditableSliderWidget::eventFilter(QObject*, QEvent* e) {
if (e->type() == QEvent::FocusIn) {
// If the edit box was previously highlighted due to an
// invalid value, un-highlight it.
mLineEdit.setProperty("ColorGroup", QString());
mLineEdit.style()->unpolish(&mLineEdit);
mLineEdit.style()->polish(&mLineEdit);
} else if (e->type() == QEvent::FocusOut) {
// When the edit box loses focus, highlight it
// if it contains an invalid value.
int dummy;
QString text = mLineEdit.text();
if (mLineEdit.validator()->validate(text, dummy) != QValidator::Acceptable) {
mLineEdit.setProperty("ColorGroup", QString("InvalidInput"));
mLineEdit.style()->unpolish(&mLineEdit);
mLineEdit.style()->polish(&mLineEdit);
}
}
return false;
}