/***************************************************************************
* 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 <QApplication>
#include <QMenu>
#include <QAction>
+#include <QLabel>
+#include <QPainter>
+#include <QStyle>
-#include <KColorScheme>
+#include <KIcon>
#include <KLocalizedString>
+#include <KGlobalSettings>
-DragValue::DragValue(QWidget* parent) :
+DragValue::DragValue(const QString &label, int defaultValue, int id, const QString suffix, QWidget* parent) :
QWidget(parent),
m_maximum(100),
m_minimum(0),
m_precision(2),
- m_step(1),
- m_dragMode(false)
+ m_default(defaultValue),
+ m_id(id)
{
- setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setFocusPolicy(Qt::StrongFocus);
setContextMenuPolicy(Qt::CustomContextMenu);
-
- QHBoxLayout *l = new QHBoxLayout(this);
+
+ QHBoxLayout *l = new QHBoxLayout;
l->setSpacing(0);
- l->setMargin(0);
-
- 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->setContentsMargins(0, 0, 0, 0);
+ m_label = new CustomLabel(label, this);
+ m_label->setCursor(Qt::PointingHandCursor);
+ m_label->setRange(m_minimum, m_maximum);
+ l->addWidget(m_label);
+ m_edit = new KIntSpinBox(this);
+ if (!suffix.isEmpty()) m_edit->setSuffix(suffix);
+
+ m_edit->setButtonSymbols(QAbstractSpinBox::NoButtons);
+ m_edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_edit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
+ m_edit->setRange(m_minimum, m_maximum);
l->addWidget(m_edit);
+ connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(m_label, SIGNAL(valueChanged(int,bool)), this, SLOT(setValue(int,bool)));
+ setLayout(l);
+ m_label->setMaximumHeight(m_edit->sizeHint().height());
m_menu = new QMenu(this);
-
- m_nonlinearScale = new QAction(i18n("Nonlinear scale"), this);
- m_nonlinearScale->setCheckable(true);
- m_nonlinearScale->setChecked(KdenliveSettings::dragvalue_nonlinear());
- m_menu->addAction(m_nonlinearScale);
-
+
+ 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);
-
- 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()));
- setStyleSheet(stylesheet);
-
- updateMaxWidth();
+
+ 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);
+ }
+
+ m_label->setRange(m_minimum, m_maximum);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotShowContextMenu(const QPoint&)));
- connect(m_nonlinearScale, SIGNAL(triggered(bool)), this, SLOT(slotSetNonlinearScale(bool)));
+ connect(m_scale, SIGNAL(triggered(int)), this, SLOT(slotSetScaleMode(int)));
connect(m_directUpdate, SIGNAL(triggered(bool)), this, SLOT(slotSetDirectUpdate(bool)));
connect(m_edit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
{
delete m_edit;
delete m_menu;
- delete m_nonlinearScale;
+ delete m_scale;
delete m_directUpdate;
}
+int DragValue::spinSize()
+{
+ return m_edit->sizeHint().width();
+}
+
+void DragValue::setSpinSize(int width)
+{
+ m_edit->setMinimumWidth(width);
+}
+
+void DragValue::slotSetInTimeline()
+{
+ emit inTimeline(m_id);
+}
+
int DragValue::precision() const
{
return m_precision;
qreal DragValue::value() const
{
- return m_edit->text().toDouble();
+ return m_edit->value();
}
void DragValue::setMaximum(qreal max)
{
m_maximum = max;
- updateMaxWidth();
+ m_label->setRange(m_minimum, m_maximum);
+ m_edit->setRange(m_minimum, m_maximum);
}
void DragValue::setMinimum(qreal min)
{
m_minimum = min;
- updateMaxWidth();
+ m_label->setRange(m_minimum, m_maximum);
+ m_edit->setRange(m_minimum, m_maximum);
}
void DragValue::setRange(qreal min, qreal max)
{
m_maximum = max;
m_minimum = min;
- updateMaxWidth();
+ m_label->setRange(m_minimum, m_maximum);
+ m_edit->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)
+void DragValue::setStep(qreal /*step*/)
{
- m_step = step;
+ //m_step = step;
}
-void DragValue::setValue(qreal value, bool final)
+void DragValue::slotReset()
{
- value = qBound(m_minimum, value, m_maximum);
+ m_edit->blockSignals(true);
+ m_edit->setValue(m_default);
+ m_label->setValue(m_default);
+ m_edit->blockSignals(false);
+ emit valueChanged(m_default, true);
+}
- m_edit->setText(QString::number(value, 'f', m_precision));
+void DragValue::slotSetValue(int value)
+{
+ setValue(value, KdenliveSettings::dragvalue_directupdate());
+}
+void DragValue::setValue(int value, bool final)
+{
+ value = qBound(m_minimum, value, m_maximum);
+ m_edit->blockSignals(true);
+ m_edit->setValue(value);
+ m_edit->blockSignals(false);
+ m_label->setValue(value);
emit valueChanged(value, final);
}
-void DragValue::mousePressEvent(QMouseEvent* e)
+void DragValue::focusInEvent(QFocusEvent* e)
{
- if (e->button() == Qt::LeftButton) {
- m_dragStartPosition = m_dragLastPosition = e->pos();
- m_dragMode = true;
- e->accept();
+ if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) {
+ //m_edit->setEnabled(true);
+ m_edit->setFocus(e->reason());
+ } else {
+ QWidget::focusInEvent(e);
}
}
-void DragValue::mouseMoveEvent(QMouseEvent* e)
+void DragValue::slotEditingFinished()
{
- if (m_dragMode && (e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
- int diff = e->x() - m_dragLastPosition.x();
+ qreal value = m_edit->value();
+ m_edit->clearFocus();
+ emit valueChanged(value, true);
+}
- if (e->modifiers() == Qt::ControlModifier)
- diff *= 2;
- else if (e->modifiers() == Qt::ShiftModifier)
- diff /= 2;
- if (KdenliveSettings::dragvalue_nonlinear())
- diff = (diff > 0 ? 1 : -1) * pow(diff, 2);
+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));
+}
- setValue(value() + diff / m_step, KdenliveSettings::dragvalue_directupdate());
- m_dragLastPosition = e->pos();
- e->accept();
- }
+void DragValue::slotSetScaleMode(int mode)
+{
+ KdenliveSettings::setDragvalue_mode(mode);
}
-void DragValue::mouseReleaseEvent(QMouseEvent* e)
+void DragValue::slotSetDirectUpdate(bool directUpdate)
{
- m_dragMode = false;
- if (m_dragLastPosition == m_dragStartPosition) {
- // value was not changed through dragging (mouse position stayed the same since mousePressEvent)
- m_edit->setEnabled(true);
- m_edit->setFocus(Qt::MouseFocusReason);
- } else {
- setValue(value(), true);
- m_dragLastPosition = m_dragStartPosition;
- e->accept();
- }
+ KdenliveSettings::setDragvalue_directupdate(directUpdate);
}
-void DragValue::wheelEvent(QWheelEvent* e)
+void DragValue::setInTimelineProperty(bool intimeline)
{
- if (e->delta() > 0)
- slotValueInc();
- else
- slotValueDec();
+ if (m_label->property("inTimeline").toBool() == intimeline) return;
+ m_label->setProperty("inTimeline", intimeline);
+ m_edit->setProperty("inTimeline", intimeline);
+ style()->unpolish(m_label);
+ style()->polish(m_label);
+ m_label->update();
+ style()->unpolish(m_edit);
+ style()->polish(m_edit);
+ m_edit->update();
}
-void DragValue::focusInEvent(QFocusEvent* e)
+CustomLabel::CustomLabel(const QString &label, QWidget* parent) :
+ QProgressBar(parent),
+ m_dragMode(false),
+ m_step(1)
+
{
- if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) {
- m_edit->setEnabled(true);
- m_edit->setFocus(e->reason());
- } else {
- QWidget::focusInEvent(e);
- }
+ setFormat(" " + label);
+ setFocusPolicy(Qt::ClickFocus);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
+ setRange(0, 100);
+ setValue(0);
+ setFont(KGlobalSettings::toolBarFont());
}
-void DragValue::slotValueInc()
+void CustomLabel::mousePressEvent(QMouseEvent* e)
{
- setValue(m_edit->text().toDouble() + m_step);
+ if (e->button() == Qt::LeftButton) {
+ m_dragStartPosition = m_dragLastPosition = e->pos();
+ e->accept();
+ }
+ else QWidget::mousePressEvent(e);
}
-void DragValue::slotValueDec()
+void CustomLabel::mouseMoveEvent(QMouseEvent* e)
{
- setValue(m_edit->text().toDouble() - m_step);
+ if ((e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
+ m_dragMode = true;
+ if (KdenliveSettings::dragvalue_mode() > 0) {
+ 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);
+
+ int nv = value() + diff / m_step;
+ if (nv != value()) setNewValue(nv, KdenliveSettings::dragvalue_directupdate());
+ }
+ else {
+ int 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::slotEditingFinished()
+void CustomLabel::mouseReleaseEvent(QMouseEvent* e)
{
- qreal value = m_edit->text().toDouble();
- m_edit->setEnabled(false);
- emit valueChanged(value, true);
+ if (e->modifiers() == Qt::ControlModifier) {
+ emit setInTimeline();
+ e->accept();
+ return;
+ }
+ if (m_dragMode) {
+ setNewValue(value(), true);
+ m_dragLastPosition = m_dragStartPosition;
+ e->accept();
+ }
+ else {
+ setNewValue((int) (minimum() + ((double)maximum() - minimum()) / width() * e->pos().x()), KdenliveSettings::dragvalue_directupdate());
+ m_dragLastPosition = m_dragStartPosition;
+ e->accept();
+ }
+ m_dragMode = false;
}
-void DragValue::updateMaxWidth()
+void CustomLabel::wheelEvent(QWheelEvent* e)
{
- 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')));
+ if (e->delta() > 0) {
+ if (e->modifiers() == Qt::ControlModifier) slotValueInc(10);
+ else slotValueInc();
+ }
+ else {
+ if (e->modifiers() == Qt::ControlModifier) slotValueDec(10);
+ else slotValueDec();
+ }
+ e->accept();
}
-void DragValue::slotShowContextMenu(const QPoint& pos)
+void CustomLabel::slotValueInc(int factor)
{
- // values might have been changed by another object of this class
- m_nonlinearScale->setChecked(KdenliveSettings::dragvalue_nonlinear());
- m_directUpdate->setChecked(KdenliveSettings::dragvalue_directupdate());
- m_menu->exec(mapToGlobal(pos));
+ setNewValue((int) (value() + m_step * factor), true);
}
-void DragValue::slotSetNonlinearScale(bool nonlinear)
+void CustomLabel::slotValueDec(int factor)
{
- KdenliveSettings::setDragvalue_nonlinear(nonlinear);
+ setNewValue((int) (value() - m_step * factor), true);
}
-void DragValue::slotSetDirectUpdate(bool directUpdate)
+void CustomLabel::setNewValue(int value, bool update)
{
- KdenliveSettings::setDragvalue_directupdate(directUpdate);
+ setValue(value);
+ emit valueChanged(value, update);
}
#include "dragvalue.moc"
+