File indexing completed on 2025-02-09 05:31:47
0001 /* This file is part of the KDE project 0002 Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Lesser General Public 0006 License as published by the Free Software Foundation; either 0007 version 2.1 of the License, or (at your option) version 3, or any 0008 later version accepted by the membership of KDE e.V. (or its 0009 successor approved by the membership of KDE e.V.), Nokia Corporation 0010 (or its successors, if any) and the KDE Free Qt Foundation, which shall 0011 act as a proxy defined in Section 6 of version 3 of the license. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Lesser General Public License for more details. 0017 0018 You should have received a copy of the GNU Lesser General Public 0019 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0020 0021 */ 0022 0023 #include "effectwidget.h" 0024 #include "effectwidget_p.h" 0025 0026 #include <QtAlgorithms> 0027 #include <QList> 0028 0029 #include "effect.h" 0030 #include "effectparameter.h" 0031 #include "phonondefs_p.h" 0032 #include <QBoxLayout> 0033 #include <QLabel> 0034 #include <QSpinBox> 0035 #include <QCheckBox> 0036 #include <QComboBox> 0037 #include <QSlider> 0038 #include <limits> 0039 0040 #ifdef min 0041 #undef min 0042 #endif 0043 #ifdef max 0044 #undef max 0045 #endif 0046 static const qreal DEFAULT_MIN = std::numeric_limits<qreal>::min(); 0047 static const qreal DEFAULT_MAX = std::numeric_limits<qreal>::max(); 0048 static const int DEFAULT_MIN_INT = std::numeric_limits<int>::min(); 0049 static const int DEFAULT_MAX_INT = std::numeric_limits<int>::max(); 0050 static const int SLIDER_RANGE = 8; 0051 static const int TICKINTERVAL = 4; 0052 0053 0054 #ifndef QT_NO_PHONON_EFFECTWIDGET 0055 0056 namespace Phonon 0057 { 0058 0059 EffectWidget::EffectWidget(Effect *effect, QWidget *parent) 0060 : QWidget(parent), 0061 k_ptr(new EffectWidgetPrivate(effect)) 0062 { 0063 P_D(EffectWidget); 0064 d->q_ptr = this; 0065 d->autogenerateUi(); 0066 } 0067 0068 EffectWidget::~EffectWidget() 0069 { 0070 delete k_ptr; 0071 } 0072 0073 /* 0074 EffectWidget::EffectWidget(EffectWidgetPrivate &dd, QWidget *parent) 0075 : QWidget(parent) 0076 , k_ptr(&dd) 0077 { 0078 P_D(EffectWidget); 0079 d->q_ptr = this; 0080 d->autogenerateUi(); 0081 } 0082 */ 0083 0084 EffectWidgetPrivate::EffectWidgetPrivate(Effect *e) 0085 : effect(e) 0086 { 0087 //TODO: look up whether there is a specialized widget for this effect. This 0088 //could be a DSO or a Designer ui file found via KTrader. 0089 // 0090 //if no specialized widget is available: 0091 } 0092 0093 void EffectWidgetPrivate::autogenerateUi() 0094 { 0095 P_Q(EffectWidget); 0096 QVBoxLayout *mainLayout = new QVBoxLayout(q); 0097 mainLayout->setContentsMargins(QMargins()); 0098 const QList<Phonon::EffectParameter> parameters = effect->parameters(); 0099 for (int i = 0; i < parameters.count(); ++i) { 0100 const EffectParameter ¶ = parameters.at(i); 0101 QVariant value = effect->parameterValue(para); 0102 QHBoxLayout *pLayout = new QHBoxLayout; 0103 mainLayout->addLayout(pLayout); 0104 0105 QLabel *label = new QLabel(q); 0106 pLayout->addWidget(label); 0107 label->setText(para.name()); 0108 #ifndef QT_NO_TOOLTIP 0109 label->setToolTip(para.description()); 0110 #endif 0111 0112 QWidget *control = nullptr; 0113 switch (int(para.type())) { 0114 case QVariant::String: 0115 { 0116 QComboBox *cb = new QComboBox(q); 0117 control = cb; 0118 if (value.type() == QVariant::Int) { 0119 //value just defines the item index 0120 for (int i = 0; i < para.possibleValues().count(); ++i) { 0121 cb->addItem(para.possibleValues().at(i).toString()); 0122 } 0123 cb->setCurrentIndex(value.toInt()); 0124 QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int))); 0125 } else { 0126 for (int i = 0; i < para.possibleValues().count(); ++i) { 0127 const QVariant &item = para.possibleValues().at(i); 0128 cb->addItem(item.toString()); 0129 if (item == value) { 0130 cb->setCurrentIndex(cb->count() - 1); 0131 } 0132 } 0133 QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString))); 0134 } 0135 } 0136 break; 0137 case QVariant::Bool: 0138 { 0139 QCheckBox *cb = new QCheckBox(q); 0140 control = cb; 0141 cb->setChecked(value.toBool()); 0142 QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool))); 0143 } 0144 break; 0145 case QVariant::Int: 0146 { 0147 QSpinBox *sb = new QSpinBox(q); 0148 control = sb; 0149 bool minValueOk = false; 0150 bool maxValueOk = false; 0151 const int minValue = para.minimumValue().toInt(&minValueOk); 0152 const int maxValue = para.maximumValue().toInt(&maxValueOk); 0153 0154 sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT); 0155 sb->setValue(value.toInt()); 0156 QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int))); 0157 } 0158 break; 0159 case QMetaType::Float: 0160 case QVariant::Double: 0161 { 0162 const qreal minValue = para.minimumValue().canConvert(QVariant::Double) ? 0163 para.minimumValue().toReal() : DEFAULT_MIN; 0164 const qreal maxValue = para.maximumValue().canConvert(QVariant::Double) ? 0165 para.maximumValue().toReal() : DEFAULT_MAX; 0166 0167 if (minValue == -1. && maxValue == 1.) { 0168 //Special case values between -1 and 1.0 to use a slider for improved usability 0169 QSlider *slider = new QSlider(Qt::Horizontal, q); 0170 control = slider; 0171 slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE); 0172 slider->setValue(int(SLIDER_RANGE * value.toReal())); 0173 slider->setTickPosition(QSlider::TicksBelow); 0174 slider->setTickInterval(TICKINTERVAL); 0175 QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int))); 0176 } else { 0177 double step = 0.1; 0178 if (qAbs(maxValue - minValue) > 50) 0179 step = 1.0; 0180 QDoubleSpinBox *sb = new QDoubleSpinBox(q); 0181 control = sb; 0182 sb->setRange(minValue, maxValue); 0183 sb->setValue(value.toDouble()); 0184 sb->setSingleStep(step); 0185 QObject::connect(sb, SIGNAL(valueChanged(double)), q, 0186 SLOT(_k_setDoubleParameter(double))); 0187 } 0188 } 0189 break; 0190 default: 0191 break; 0192 } 0193 0194 if (control) { 0195 #ifndef QT_NO_TOOLTIP 0196 control->setToolTip(para.description()); 0197 #endif 0198 #ifndef QT_NO_SHORTCUT 0199 label->setBuddy(control); 0200 #endif 0201 pLayout->addWidget(control); 0202 parameterForObject.insert(control, para); 0203 } 0204 } 0205 } 0206 0207 void EffectWidgetPrivate::_k_setToggleParameter(bool checked) 0208 { 0209 P_Q(EffectWidget); 0210 if (parameterForObject.contains(q->sender())) { 0211 effect->setParameterValue(parameterForObject[q->sender()], checked); 0212 } 0213 } 0214 0215 void EffectWidgetPrivate::_k_setIntParameter(int value) 0216 { 0217 P_Q(EffectWidget); 0218 if (parameterForObject.contains(q->sender())) { 0219 effect->setParameterValue(parameterForObject[q->sender()], value); 0220 } 0221 } 0222 0223 void EffectWidgetPrivate::_k_setDoubleParameter(double value) 0224 { 0225 P_Q(EffectWidget); 0226 if (parameterForObject.contains(q->sender())) { 0227 effect->setParameterValue(parameterForObject[q->sender()], value); 0228 } 0229 } 0230 0231 void EffectWidgetPrivate::_k_setStringParameter(const QString &value) 0232 { 0233 P_Q(EffectWidget); 0234 if (parameterForObject.contains(q->sender())) { 0235 effect->setParameterValue(parameterForObject[q->sender()], value); 0236 } 0237 } 0238 0239 void EffectWidgetPrivate::_k_setSliderParameter(int value) 0240 { 0241 P_Q(EffectWidget); 0242 if (parameterForObject.contains(q->sender())) { 0243 effect->setParameterValue(parameterForObject[q->sender()], double(value) / double(SLIDER_RANGE)); 0244 } 0245 } 0246 0247 0248 } // namespace Phonon 0249 0250 0251 #endif // QT_NO_PHONON_EFFECTWIDGET 0252 0253 #include "moc_effectwidget.cpp" 0254 0255 // vim: sw=4 ts=4