1 /***************************************************************************
2 * Copyright (C) 2011 by Till Theato (root@ttill.de) *
3 * This file is part of Kdenlive (www.kdenlive.org). *
5 * Kdenlive is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Kdenlive is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 #include "dragvalue.h"
20 #include "kdenlivesettings.h"
24 #include <QHBoxLayout>
25 #include <QToolButton>
27 #include <QDoubleValidator>
28 #include <QIntValidator>
29 #include <QMouseEvent>
30 #include <QFocusEvent>
31 #include <QWheelEvent>
32 #include <QApplication>
36 #include <KColorScheme>
37 #include <KLocalizedString>
39 DragValue::DragValue(QWidget* parent) :
47 setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
48 setFocusPolicy(Qt::StrongFocus);
49 setContextMenuPolicy(Qt::CustomContextMenu);
51 QHBoxLayout *l = new QHBoxLayout(this);
55 m_edit = new QLineEdit(this);
56 m_edit->setValidator(new QDoubleValidator(m_minimum, m_maximum, m_precision, this));
57 m_edit->setAlignment(Qt::AlignCenter);
58 m_edit->setEnabled(false);
61 m_menu = new QMenu(this);
63 m_nonlinearScale = new QAction(i18n("Nonlinear scale"), this);
64 m_nonlinearScale->setCheckable(true);
65 m_nonlinearScale->setChecked(KdenliveSettings::dragvalue_nonlinear());
66 m_menu->addAction(m_nonlinearScale);
68 m_directUpdate = new QAction(i18n("Direct update"), this);
69 m_directUpdate->setCheckable(true);
70 m_directUpdate->setChecked(KdenliveSettings::dragvalue_directupdate());
71 m_menu->addAction(m_directUpdate);
73 QPalette p = palette();
74 KColorScheme scheme(p.currentColorGroup(), KColorScheme::View, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
75 QColor bg = scheme.background(KColorScheme::LinkBackground).color();
76 QColor fg = scheme.foreground(KColorScheme::LinkText).color();
77 QColor editbg = scheme.background(KColorScheme::ActiveBackground).color();
78 QColor editfg = scheme.foreground(KColorScheme::ActiveText).color();
79 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); }")
80 .arg(bg.red()).arg(bg.green()).arg(bg.blue())
81 .arg(fg.red()).arg(fg.green()).arg(fg.blue()));
82 stylesheet.append(QString("QLineEdit::focus, QLineEdit::enabled { background-color: rgb(%1, %2, %3); color: rgb(%4, %5, %6); }")
83 .arg(editbg.red()).arg(editbg.green()).arg(editbg.blue())
84 .arg(editfg.red()).arg(editfg.green()).arg(editfg.blue()));
85 setStyleSheet(stylesheet);
89 connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotShowContextMenu(const QPoint&)));
90 connect(m_nonlinearScale, SIGNAL(triggered(bool)), this, SLOT(slotSetNonlinearScale(bool)));
91 connect(m_directUpdate, SIGNAL(triggered(bool)), this, SLOT(slotSetDirectUpdate(bool)));
93 connect(m_edit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
96 DragValue::~DragValue()
100 delete m_nonlinearScale;
101 delete m_directUpdate;
104 int DragValue::precision() const
109 qreal DragValue::maximum() const
114 qreal DragValue::minimum() const
119 qreal DragValue::value() const
121 return m_edit->text().toDouble();
124 void DragValue::setMaximum(qreal max)
130 void DragValue::setMinimum(qreal min)
136 void DragValue::setRange(qreal min, qreal max)
143 void DragValue::setPrecision(int precision)
145 m_precision = precision;
147 m_edit->setValidator(new QIntValidator(m_minimum, m_maximum, this));
149 m_edit->setValidator(new QDoubleValidator(m_minimum, m_maximum, precision, this));
152 void DragValue::setStep(qreal step)
157 void DragValue::setValue(qreal value, bool final)
159 value = qBound(m_minimum, value, m_maximum);
161 m_edit->setText(QString::number(value, 'f', m_precision));
163 emit valueChanged(value, final);
166 void DragValue::mousePressEvent(QMouseEvent* e)
168 if (e->button() == Qt::LeftButton) {
169 m_dragStartPosition = m_dragLastPosition = e->pos();
175 void DragValue::mouseMoveEvent(QMouseEvent* e)
177 if (m_dragMode && (e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
178 int diff = e->x() - m_dragLastPosition.x();
180 if (e->modifiers() == Qt::ControlModifier)
182 else if (e->modifiers() == Qt::ShiftModifier)
184 if (KdenliveSettings::dragvalue_nonlinear())
185 diff = (diff > 0 ? 1 : -1) * pow(diff, 2);
187 setValue(value() + diff / m_step, KdenliveSettings::dragvalue_directupdate());
188 m_dragLastPosition = e->pos();
193 void DragValue::mouseReleaseEvent(QMouseEvent* e)
196 if (m_dragLastPosition == m_dragStartPosition) {
197 // value was not changed through dragging (mouse position stayed the same since mousePressEvent)
198 m_edit->setEnabled(true);
199 m_edit->setFocus(Qt::MouseFocusReason);
201 setValue(value(), true);
202 m_dragLastPosition = m_dragStartPosition;
207 void DragValue::wheelEvent(QWheelEvent* e)
215 void DragValue::focusInEvent(QFocusEvent* e)
217 if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) {
218 m_edit->setEnabled(true);
219 m_edit->setFocus(e->reason());
221 QWidget::focusInEvent(e);
225 void DragValue::slotValueInc()
227 setValue(m_edit->text().toDouble() + m_step);
230 void DragValue::slotValueDec()
232 setValue(m_edit->text().toDouble() - m_step);
235 void DragValue::slotEditingFinished()
237 qreal value = m_edit->text().toDouble();
238 m_edit->setEnabled(false);
239 emit valueChanged(value, true);
242 void DragValue::updateMaxWidth()
244 int val = (int)(log10(qAbs(m_maximum) > qAbs(m_minimum) ? qAbs(m_maximum) : qAbs(m_minimum)) + .5);
250 QFontMetrics fm = m_edit->fontMetrics();
251 m_edit->setMaximumWidth(fm.width(QString().rightJustified(val, '8')));
254 void DragValue::slotShowContextMenu(const QPoint& pos)
256 // values might have been changed by another object of this class
257 m_nonlinearScale->setChecked(KdenliveSettings::dragvalue_nonlinear());
258 m_directUpdate->setChecked(KdenliveSettings::dragvalue_directupdate());
259 m_menu->exec(mapToGlobal(pos));
262 void DragValue::slotSetNonlinearScale(bool nonlinear)
264 KdenliveSettings::setDragvalue_nonlinear(nonlinear);
267 void DragValue::slotSetDirectUpdate(bool directUpdate)
269 KdenliveSettings::setDragvalue_directupdate(directUpdate);
272 #include "dragvalue.moc"