]> git.sesse.net Git - kdenlive/blobdiff - src/dragvalue.cpp
Integrate with the required MLT hooks for getting Movit to work.
[kdenlive] / src / dragvalue.cpp
index 279cf02519fd957c9a9f8fc40d4a625bb8483919..64a8f2eec69f53b43f8ed4c0ffc14f31fc13aa5e 100644 (file)
@@ -1,5 +1,6 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Till Theato (root@ttill.de)                     *
+ *   Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
  *   This file is part of Kdenlive (www.kdenlive.org).                     *
  *                                                                         *
  *   Kdenlive is free software: you can redistribute it and/or modify      *
 #include <QFocusEvent>
 #include <QWheelEvent>
 #include <QApplication>
+#include <QMenu>
+#include <QAction>
+#include <QLabel>
+#include <QPainter>
+#include <QStyle>
 
-#include <KColorScheme>
+#include <KDebug>
 #include <KIcon>
-
-DragValue::DragValue(QWidget* parent) :
-        QWidget(parent),
-        m_maximum(100),
-        m_minimum(0),
-        m_precision(2),
-        m_step(1),
-        m_dragMode(false),
-        m_finalValue(true)
+#include <KLocalizedString>
+#include <KGlobalSettings>
+
+
+DragValue::DragValue(const QString &label, double defaultValue, int decimals, double min, double max, int id, const QString &suffix, bool showSlider, QWidget* parent) :
+    QWidget(parent),
+    m_maximum(max),
+    m_minimum(min),
+    m_decimals(decimals),
+    m_default(defaultValue),
+    m_id(id),
+    m_intEdit(NULL),
+    m_doubleEdit(NULL)
 {
-    setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+    if (showSlider) setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+    else setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
     setFocusPolicy(Qt::StrongFocus);
-
-    QHBoxLayout *l = new QHBoxLayout(this);
+    setContextMenuPolicy(Qt::CustomContextMenu);
+    setFocusPolicy(Qt::StrongFocus);
+    
+    QHBoxLayout *l = new QHBoxLayout;
     l->setSpacing(0);
-    l->setMargin(0);
-
-    /*m_buttonDec = new QToolButton(this);
-    m_buttonDec->setIcon(KIcon("arrow-left"));
-    m_buttonDec->setIconSize(QSize(12, 12));
-    m_buttonDec->setObjectName("ButtonDec");
-    l->addWidget(m_buttonDec);*/
-
-    m_edit = new QLineEdit(this);
-    m_edit->setValidator(new QDoubleValidator(m_minimum, m_maximum, m_precision, this));
-    m_edit->setAlignment(Qt::AlignCenter);
-    m_edit->setEnabled(false);
-    l->addWidget(m_edit);
-
-    /*m_buttonInc = new QToolButton(this);
-    m_buttonInc->setIcon(KIcon("arrow-right"));
-    m_buttonInc->setIconSize(QSize(12, 12));
-    m_buttonInc->setObjectName("ButtonInc");
-    l->addWidget(m_buttonInc);*/
-
-    QPalette p = palette();
-    KColorScheme scheme(p.currentColorGroup(), KColorScheme::View, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
-    QColor bg = scheme.background(KColorScheme::LinkBackground).color();
-    QColor fg = scheme.foreground(KColorScheme::LinkText).color();
-    QColor editbg = scheme.background(KColorScheme::ActiveBackground).color();
-    QColor editfg = scheme.foreground(KColorScheme::ActiveText).color();
-    QString stylesheet(QString("QLineEdit { background-color: rgb(%1, %2, %3); border: 1px solid rgb(%1, %2, %3); border-radius: 5px; padding: 0px; color: rgb(%4, %5, %6); } QLineEdit::disabled { color: rgb(%4, %5, %6); }")
-                        .arg(bg.red()).arg(bg.green()).arg(bg.blue())
-                        .arg(fg.red()).arg(fg.green()).arg(fg.blue()));
-    stylesheet.append(QString("QLineEdit::focus, QLineEdit::enabled { background-color: rgb(%1, %2, %3); color: rgb(%4, %5, %6); }")
-                        .arg(editbg.red()).arg(editbg.green()).arg(editbg.blue())
-                        .arg(editfg.red()).arg(editfg.green()).arg(editfg.blue()));
-/*     QString stylesheet(QString("QLineEdit { background-color: rgb(%1, %2, %3); border: 1px solid rgb(%1, %2, %3); padding: 2px; padding-bottom: 0px; border-top-left-radius: 7px; border-top-right-radius: 7px; }")
-                         .arg(bg.red()).arg(bg.green()).arg(bg.blue()));
-     stylesheet.append(QString("QLineEdit::focus, QLineEdit::enabled { background-color: rgb(%1, %2, %3); color: rgb(%4, %5, %6); }")
-                         .arg(textbg.red()).arg(textbg.green()).arg(textbg.blue())
-                         .arg(textfg.red()).arg(textfg.green()).arg(textfg.blue()));
-    QString stylesheet(QString("* { background-color: rgb(%1, %2, %3); margin: 0px; }").arg(bg.red()).arg(bg.green()).arg(bg.blue()));
-    stylesheet.append(QString("QLineEdit { border: 0px; height: 100%; } QLineEdit::focus, QLineEdit::enabled { background-color: rgb(%1, %2, %3); color: rgb(%4, %5, %6); }")
-                         .arg(textbg.red()).arg(textbg.green()).arg(textbg.blue())
-                         .arg(textfg.red()).arg(textfg.green()).arg(textfg.blue()));
-    stylesheet.append(QString("QToolButton { border: 1px solid rgb(%1, %2, %3); }").arg(bg.red()).arg(bg.green()).arg(bg.blue()));
-    stylesheet.append(QString("QToolButton#ButtonDec { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }"));
-    stylesheet.append(QString("QToolButton#ButtonInc { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }"));*/
-    setStyleSheet(stylesheet);
-
-    updateMaxWidth();
-
-    /*connect(m_buttonDec, SIGNAL(clicked(bool)), this, SLOT(slotValueDec()));
-    connect(m_buttonInc, SIGNAL(clicked(bool)), this, SLOT(slotValueInc()));*/
-    connect(m_edit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
+    l->setContentsMargins(0, 0, 0, 0);
+    m_label = new CustomLabel(label, showSlider, m_maximum - m_minimum, this);
+    l->addWidget(m_label);
+    if (decimals == 0) {
+        m_label->setMaximum(max - min);
+        m_label->setStep(1);
+        m_intEdit = new QSpinBox(this);
+        m_intEdit->setObjectName("dragBox");
+        m_intEdit->setFocusPolicy(Qt::StrongFocus);
+        if (!suffix.isEmpty()) m_intEdit->setSuffix(suffix);
+        m_intEdit->setKeyboardTracking(false);
+        m_intEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+        m_intEdit->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+        m_intEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+        m_intEdit->setRange((int) m_minimum, (int)m_maximum);
+        l->addWidget(m_intEdit);
+        connect(m_intEdit, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+        connect(m_intEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
+    } else {
+        m_doubleEdit = new QDoubleSpinBox(this);
+        m_doubleEdit->setDecimals(decimals);
+        m_doubleEdit->setFocusPolicy(Qt::StrongFocus);
+        m_doubleEdit->setObjectName("dragBox");
+        if (!suffix.isEmpty()) m_doubleEdit->setSuffix(suffix);
+        m_doubleEdit->setKeyboardTracking(false);
+        m_doubleEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+        m_doubleEdit->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+        m_doubleEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+        m_doubleEdit->setRange(m_minimum, m_maximum);
+        double factor = 100;
+        if (m_maximum - m_minimum > 10000) factor = 1000;
+        m_label->setStep(1);
+        m_doubleEdit->setSingleStep((m_maximum - m_minimum) / factor);
+        l->addWidget(m_doubleEdit);
+        connect(m_doubleEdit, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double)));
+        connect(m_doubleEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
+    }
+    
+    connect(m_label, SIGNAL(valueChanged(double,bool)), this, SLOT(setValueFromProgress(double,bool)));
+    connect(m_label, SIGNAL(resetValue()), this, SLOT(slotReset()));
+    setLayout(l);
+    if (m_intEdit)
+        m_label->setMaximumHeight(m_intEdit->sizeHint().height());
+    else
+        m_label->setMaximumHeight(m_doubleEdit->sizeHint().height());
+
+    m_menu = new QMenu(this);
+
+    m_scale = new KSelectAction(i18n("Scaling"), this);
+    m_scale->addAction(i18n("Normal scale"));
+    m_scale->addAction(i18n("Pixel scale"));
+    m_scale->addAction(i18n("Nonlinear scale"));
+    m_scale->setCurrentItem(KdenliveSettings::dragvalue_mode());
+    m_menu->addAction(m_scale);
+    
+    m_directUpdate = new QAction(i18n("Direct update"), this);
+    m_directUpdate->setCheckable(true);
+    m_directUpdate->setChecked(KdenliveSettings::dragvalue_directupdate());
+    m_menu->addAction(m_directUpdate);
+    
+    QAction *reset = new QAction(KIcon("edit-undo"), i18n("Reset value"), this);
+    connect(reset, SIGNAL(triggered()), this, SLOT(slotReset()));
+    m_menu->addAction(reset);
+    
+    if (m_id > -1) {
+        QAction *timeline = new QAction(KIcon("go-jump"), i18n("Show %1 in timeline", label), this);
+        connect(timeline, SIGNAL(triggered()), this, SLOT(slotSetInTimeline()));
+        connect(m_label, SIGNAL(setInTimeline()), this, SLOT(slotSetInTimeline()));
+        m_menu->addAction(timeline);
+    }
+
+    connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotShowContextMenu(QPoint)));
+    connect(m_scale, SIGNAL(triggered(int)), this, SLOT(slotSetScaleMode(int)));
+    connect(m_directUpdate, SIGNAL(triggered(bool)), this, SLOT(slotSetDirectUpdate(bool)));
 }
 
+
 DragValue::~DragValue()
 {
-    delete m_edit;
-    /*delete m_buttonInc;
-    delete m_buttonDec;*/
+    delete m_intEdit;
+    delete m_doubleEdit;
+    delete m_menu;
+    //delete m_scale;
+    //delete m_directUpdate;
+}
+
+int DragValue::spinSize()
+{
+    if (m_intEdit)
+        return m_intEdit->sizeHint().width();
+    else
+        return m_doubleEdit->sizeHint().width();
+}
+
+void DragValue::setSpinSize(int width)
+{
+    if (m_intEdit)
+        m_intEdit->setMinimumWidth(width);
+    else
+        m_doubleEdit->setMinimumWidth(width);
+}
+
+void DragValue::slotSetInTimeline()
+{
+    emit inTimeline(m_id);
 }
 
 int DragValue::precision() const
 {
-    return m_precision;
+    return m_decimals;
 }
 
 qreal DragValue::maximum() const
@@ -125,130 +185,338 @@ qreal DragValue::minimum() const
 
 qreal DragValue::value() const
 {
-    return m_edit->text().toDouble();
+    if (m_intEdit) return m_intEdit->value();
+    else return m_doubleEdit->value();
 }
 
 void DragValue::setMaximum(qreal max)
 {
-    m_maximum = max;
-    updateMaxWidth();
+    if (m_maximum != max) {
+        m_maximum = max;
+        if (m_intEdit)
+            m_intEdit->setRange(m_minimum, m_maximum);
+        else
+            m_doubleEdit->setRange(m_minimum, m_maximum);
+    }
 }
 
 void DragValue::setMinimum(qreal min)
 {
-    m_minimum = min;
-    updateMaxWidth();
+    if (m_minimum != min) {
+        m_minimum = min;
+        if (m_intEdit)
+            m_intEdit->setRange(m_minimum, m_maximum);
+        else
+            m_doubleEdit->setRange(m_minimum, m_maximum);
+    }
 }
 
 void DragValue::setRange(qreal min, qreal max)
 {
     m_maximum = max;
     m_minimum = min;
-    updateMaxWidth();
+    if (m_intEdit)
+        m_intEdit->setRange(m_minimum, m_maximum);
+    else
+        m_doubleEdit->setRange(m_minimum, m_maximum);
 }
 
-void DragValue::setPrecision(int precision)
+void DragValue::setPrecision(int /*precision*/)
 {
-    m_precision = precision;
+    //TODO: Not implemented, in case we need double value, we should replace the KIntSpinBox with KDoubleNumInput...
+    /*m_precision = precision;
     if (precision == 0)
         m_edit->setValidator(new QIntValidator(m_minimum, m_maximum, this));
     else
-        m_edit->setValidator(new QDoubleValidator(m_minimum, m_maximum, precision, this));
+        m_edit->setValidator(new QDoubleValidator(m_minimum, m_maximum, precision, this));*/
 }
 
 void DragValue::setStep(qreal step)
 {
-    m_step = step;
+    if (m_intEdit)
+        m_intEdit->setSingleStep(step);
+    else
+        m_doubleEdit->setSingleStep(step);
 }
 
-void DragValue::setValue(qreal value, bool final)
+void DragValue::slotReset()
+{
+    if (m_intEdit) {
+        m_intEdit->blockSignals(true);
+        m_intEdit->setValue(m_default);
+        m_intEdit->blockSignals(false);
+        emit valueChanged((int) m_default, true);
+    }
+    else {
+        m_doubleEdit->blockSignals(true);
+        m_doubleEdit->setValue(m_default);
+        m_doubleEdit->blockSignals(false);
+        emit valueChanged(m_default, true);
+    }
+    m_label->setProgressValue((m_default - m_minimum) / (m_maximum - m_minimum) * m_label->maximum());
+}
+
+void DragValue::slotSetValue(int value)
+{
+    setValue(value, true);
+}
+
+void DragValue::slotSetValue(double value)
+{
+    setValue(value, true);
+}
+
+void DragValue::setValueFromProgress(double value, bool final)
+{
+    value = m_minimum + value * (m_maximum - m_minimum) / m_label->maximum();
+    if (m_decimals == 0)
+        setValue(qRound(value), final);
+    else
+        setValue(value, final);
+}
+
+void DragValue::setValue(double value, bool final)
 {
-    m_finalValue = final;
     value = qBound(m_minimum, value, m_maximum);
+    if (m_intEdit) {
+        m_intEdit->blockSignals(true);
+        m_intEdit->setValue((int) value);
+        m_intEdit->blockSignals(false);
+        emit valueChanged((int) value, final);
+    }
+    else {
+        m_doubleEdit->blockSignals(true);
+        m_doubleEdit->setValue(value);
+        m_doubleEdit->blockSignals(false);
+        emit valueChanged(value, final);
+    }
 
-    m_edit->setText(QString::number(value, 'f', m_precision));
+    m_label->setProgressValue((value - m_minimum) / (m_maximum - m_minimum) * m_label->maximum());
+}
 
-    emit valueChanged(value, final);
+void DragValue::focusOutEvent(QFocusEvent*)
+{
+    if (m_intEdit) m_intEdit->setFocusPolicy(Qt::StrongFocus);
+    else m_doubleEdit->setFocusPolicy(Qt::StrongFocus);
 }
 
-void DragValue::mousePressEvent(QMouseEvent* e)
+void DragValue::focusInEvent(QFocusEvent* e)
+{
+    if (m_intEdit)
+        m_intEdit->setFocusPolicy(Qt::WheelFocus);
+    else
+        m_doubleEdit->setFocusPolicy(Qt::WheelFocus);
+
+    if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) {
+        if (m_intEdit) m_intEdit->setFocus(e->reason());
+        else m_doubleEdit->setFocus(e->reason());
+    } else {
+        QWidget::focusInEvent(e);
+    }
+}
+
+void DragValue::slotEditingFinished()
+{
+    if (m_intEdit) {
+        int value = m_intEdit->value();
+        m_intEdit->blockSignals(true);
+        m_intEdit->clearFocus();
+        m_intEdit->blockSignals(false);
+        if (!KdenliveSettings::dragvalue_directupdate()) emit valueChanged((double) value, true);
+    }
+    else {
+        double value = m_doubleEdit->value();
+        m_doubleEdit->blockSignals(true);
+        m_doubleEdit->clearFocus();
+        m_doubleEdit->blockSignals(false);
+        if (!KdenliveSettings::dragvalue_directupdate()) emit valueChanged(value, true);
+    }
+}
+
+void DragValue::slotShowContextMenu(const QPoint& pos)
+{
+    // values might have been changed by another object of this class
+    m_scale->setCurrentItem(KdenliveSettings::dragvalue_mode());
+    m_directUpdate->setChecked(KdenliveSettings::dragvalue_directupdate());
+    m_menu->exec(mapToGlobal(pos));
+}
+
+void DragValue::slotSetScaleMode(int mode)
+{
+    KdenliveSettings::setDragvalue_mode(mode);
+}
+
+void DragValue::slotSetDirectUpdate(bool directUpdate)
+{
+    KdenliveSettings::setDragvalue_directupdate(directUpdate);
+}
+
+void DragValue::setInTimelineProperty(bool intimeline)
+{
+    if (m_label->property("inTimeline").toBool() == intimeline) return;
+    m_label->setProperty("inTimeline", intimeline);
+    style()->unpolish(m_label);
+    style()->polish(m_label);
+    m_label->update();
+    if (m_intEdit) {
+        m_intEdit->setProperty("inTimeline", intimeline);
+        style()->unpolish(m_intEdit);
+        style()->polish(m_intEdit);
+        m_intEdit->update();
+    }
+    else {
+        m_doubleEdit->setProperty("inTimeline", intimeline);
+        style()->unpolish(m_doubleEdit);
+        style()->polish(m_doubleEdit);
+        m_doubleEdit->update();
+    }
+    
+}
+
+CustomLabel::CustomLabel(const QString &label, bool showSlider, int range, QWidget* parent) :
+    QProgressBar(parent),
+    m_dragMode(false),
+    m_showSlider(showSlider),
+    m_step(10.0)
+  //m_precision(pow(10, precision)),
+{
+    setFont(KGlobalSettings::toolBarFont());
+    setFormat(' ' + label);
+    setFocusPolicy(Qt::StrongFocus);
+    setCursor(Qt::PointingHandCursor);
+    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
+    if (showSlider) setRange(0, 1000);
+    else {
+        setRange(0, range);
+        QSize sh;
+        const QFontMetrics &fm = fontMetrics();
+        sh.setWidth(fm.width(' ' + label + ' '));
+        setMaximumWidth(sh.width());
+        setObjectName("dragOnly");
+    }
+    setValue(0);
+}
+
+void CustomLabel::mousePressEvent(QMouseEvent* e)
 {
     if (e->button() == Qt::LeftButton) {
         m_dragStartPosition = m_dragLastPosition = e->pos();
-        m_dragMode = true;
         e->accept();
     }
+    else if (e->button() == Qt::MidButton) {
+        emit resetValue();
+        m_dragStartPosition = QPoint(-1, -1);
+    }
+    else QWidget::mousePressEvent(e);
 }
 
-void DragValue::mouseMoveEvent(QMouseEvent* e)
+void CustomLabel::mouseMoveEvent(QMouseEvent* e)
 {
-    if (m_dragMode && (e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
-        int diffDistance = e->x() - m_dragLastPosition.x();
-        int direction = diffDistance > 0 ? 1 : -1; // since pow loses this info
-        setValue(value() + direction * pow(e->x() - m_dragLastPosition.x(), 2) / m_step, false);
-        m_dragLastPosition = e->pos();
-        e->accept();
+    if (m_dragStartPosition != QPoint(-1, -1)) {
+        if (!m_dragMode && (e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
+            m_dragMode = true;
+            m_dragLastPosition = e->pos();
+            e->accept();
+            return;
+        }
+        if (m_dragMode) {
+            if (KdenliveSettings::dragvalue_mode() > 0 || !m_showSlider) {
+                int diff = e->x() - m_dragLastPosition.x();
+
+                if (e->modifiers() == Qt::ControlModifier)
+                    diff *= 2;
+                else if (e->modifiers() == Qt::ShiftModifier)
+                    diff /= 2;
+                if (KdenliveSettings::dragvalue_mode() == 2)
+                    diff = (diff > 0 ? 1 : -1) * pow(diff, 2);
+
+                double nv = value() + diff * m_step;
+                if (nv != value()) setNewValue(nv, KdenliveSettings::dragvalue_directupdate());
+            }
+            else {
+                double nv = minimum() + ((double) maximum() - minimum()) / width() * e->pos().x();
+                if (nv != value()) setNewValue(nv, KdenliveSettings::dragvalue_directupdate());
+            }
+            m_dragLastPosition = e->pos();
+            e->accept();
+        }
     }
+    else QWidget::mouseMoveEvent(e);
 }
 
-void DragValue::mouseReleaseEvent(QMouseEvent* e)
+void CustomLabel::mouseReleaseEvent(QMouseEvent* e)
 {
-    m_dragMode = false;
-    if (m_finalValue) {
-        m_edit->setEnabled(true);
-        m_edit->setFocus(Qt::MouseFocusReason);
-    } else {
-        setValue(value(), true);
+    if (e->button() == Qt::MidButton) {
+        e->accept();
+        return;
+    }
+    if (e->modifiers() == Qt::ControlModifier) {
+        emit setInTimeline();
+        e->accept();
+        return;
+    }
+    if (m_dragMode) {
+        setNewValue(value(), true);
+        m_dragLastPosition = m_dragStartPosition;
         e->accept();
     }
+    else if (m_showSlider) {
+        setNewValue((double) maximum() * e->pos().x() / width(), true);
+        m_dragLastPosition = m_dragStartPosition;
+        e->accept();
+    }
+    m_dragMode = false;
 }
 
-void DragValue::wheelEvent(QWheelEvent* e)
+void CustomLabel::wheelEvent(QWheelEvent* e)
 {
-    if (e->delta() > 0)
-        slotValueInc();
-    else
-        slotValueDec();
+    if (e->delta() > 0) {
+        if (e->modifiers() == Qt::ControlModifier) slotValueInc(10);
+        else if (e->modifiers() == Qt::AltModifier) slotValueInc(0.1);
+        else slotValueInc();
+    }
+    else {
+        if (e->modifiers() == Qt::ControlModifier) slotValueDec(10);
+        else if (e->modifiers() == Qt::AltModifier) slotValueDec(0.1);
+        else slotValueDec();
+    }
+    e->accept();
 }
 
-void DragValue::focusInEvent(QFocusEvent* e)
+void CustomLabel::slotValueInc(double factor)
 {
-    if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) {
-        m_edit->setEnabled(true);
-        m_edit->setFocus(e->reason());
-    } else {
-        QWidget::focusInEvent(e);
-    }
+    setNewValue(value() + m_step * factor, true);
 }
 
-void DragValue::slotValueInc()
+void CustomLabel::slotValueDec(double factor)
 {
-    setValue(m_edit->text().toDouble() + m_step);
+    setNewValue(value() - m_step * factor, true);
 }
 
-void DragValue::slotValueDec()
+void CustomLabel::setProgressValue(double value)
 {
-    setValue(m_edit->text().toDouble() - m_step);
+    setValue(qRound(value));
 }
 
-void DragValue::slotEditingFinished()
+void CustomLabel::setNewValue(double value, bool update)
 {
-    m_finalValue = true;
-    qreal value = m_edit->text().toDouble();
-    m_edit->setEnabled(false);
-    emit valueChanged(value, true);
+    setValue(qRound(value));
+    emit valueChanged(qRound(value), update);
 }
 
-void DragValue::updateMaxWidth()
+void CustomLabel::setStep(double step)
 {
-    int val = (int)(log10(qAbs(m_maximum) > qAbs(m_minimum) ? qAbs(m_maximum) : qAbs(m_minimum)) + .5);
-    val += m_precision;
-    if (m_precision)
-        val += 1;
-    if (m_minimum < 0)
-        val += 1;
-    QFontMetrics fm = m_edit->fontMetrics();
-    m_edit->setMaximumWidth(fm.width(QString().rightJustified(val, '8')));
+    m_step = step;
+}
+
+void CustomLabel::focusInEvent(QFocusEvent*)
+{
+    setFocusPolicy(Qt::WheelFocus);
+}
+
+void CustomLabel::focusOutEvent(QFocusEvent*)
+{
+    setFocusPolicy(Qt::StrongFocus);
 }
 
 #include "dragvalue.moc"