13const QColor VuoInputEditorMovieFormat::darkModeEnabledLabelTextColor = QColor(207, 207, 207);
14const QColor VuoInputEditorMovieFormat::darkModeDisabledLabelTextColor = QColor(127, 127, 127);
36 const int decimalPrecision = DBL_MAX_10_EXP + DBL_DIG;
38 suggestedMinImageQuality = 0;
39 suggestedMaxImageQuality = 1;
41 suggestedMinAudioQuality = 0;
42 suggestedMaxAudioQuality = 1;
44 double suggestedStepImageQuality = 0.1;
45 double suggestedStepAudioQuality = 0.1;
47 QDoubleValidator *validator =
new QDoubleValidator(
this);
48 validator->setDecimals(decimalPrecision);
51 tabCycleForward =
true;
57 if (json_object_object_get_ex(details,
"isDark", &darkMode))
58 isDark = json_object_get_boolean(darkMode);
61 if (json_object_object_get_ex(details,
"forwardTabTraversal", &forwardTabTraversal))
62 tabCycleForward = json_object_get_boolean(forwardTabTraversal);
66 if (json_object_object_get_ex(details,
"suggestedMin", &suggestedMinValue))
74 if (json_object_object_get_ex(details,
"suggestedMax", &suggestedMaxValue))
82 if (json_object_object_get_ex(details,
"suggestedStep", &suggestedStepValue))
95 comboBoxImageEncoding->setFont(font);
96 comboBoxImageEncoding->resize(220, comboBoxImageEncoding->height());
97 setUpComboBoxForType(comboBoxImageEncoding,
"VuoMovieImageEncoding", originalMovieImageEncodingAsString);
98 connect(comboBoxImageEncoding,
static_cast<void (QComboBox::*)(
int)
>(&QComboBox::currentIndexChanged),
this, &VuoInputEditorMovieFormat::updateQualitySliderEnabledStatusAndEmitValueChanged);
102 comboBoxAudioEncoding->setFont(font);
103 setUpComboBoxForType(comboBoxAudioEncoding,
"VuoAudioEncoding", originalAudioEncodingAsString);
104 connect(comboBoxAudioEncoding,
static_cast<void (QComboBox::*)(
int)
>(&QComboBox::currentIndexChanged),
this, &VuoInputEditorMovieFormat::updateQualitySliderEnabledStatusAndEmitValueChanged);
110 lineEditImageQuality =
new QLineEdit(&dialog);
111 lineEditImageQuality->setFont(font);
113 lineEditImageQuality->adjustSize();
115 lineEditImageQuality->setValidator(validator);
116 lineEditImageQuality->installEventFilter(
this);
118 sliderImageQuality =
new QSlider(&dialog);
119 sliderImageQuality->setOrientation(Qt::Horizontal);
120 sliderImageQuality->setFocusPolicy(Qt::NoFocus);
121 sliderImageQuality->setMinimum(0);
122 sliderImageQuality->setMaximum(sliderImageQuality->width());
123 sliderImageQuality->setSingleStep(fmax(1, suggestedStepImageQuality*(sliderImageQuality->maximum()-sliderImageQuality->minimum())/(suggestedMaxImageQuality-suggestedMinImageQuality)));
126 int sliderValueImageQuality = lineEditValueToScaledSliderValue(lineEditValueImageQuality, imageQuality);
127 sliderImageQuality->setValue(sliderValueImageQuality);
129 connect(sliderImageQuality, &QSlider::valueChanged,
this,
static_cast<void (
VuoInputEditorMovieFormat::*)(
int)
>(&VuoInputEditorMovieFormat::updateLineEditValue));
130 connect(lineEditImageQuality, &QLineEdit::textEdited,
this, &VuoInputEditorMovieFormat::updateSliderValue);
131 connect(lineEditImageQuality, &QLineEdit::editingFinished,
this, &VuoInputEditorMovieFormat::emitValueChanged);
134 lineEditAudioQuality =
new QLineEdit(&dialog);
135 lineEditAudioQuality->setFont(font);
137 lineEditAudioQuality->adjustSize();
139 lineEditAudioQuality->setValidator(validator);
140 lineEditAudioQuality->installEventFilter(
this);
142 sliderAudioQuality =
new QSlider(&dialog);
143 sliderAudioQuality->setOrientation(Qt::Horizontal);
144 sliderAudioQuality->setFocusPolicy(Qt::NoFocus);
145 sliderAudioQuality->setMinimum(0);
146 sliderAudioQuality->setMaximum(sliderAudioQuality->width());
147 sliderAudioQuality->setSingleStep(fmax(1, suggestedStepAudioQuality*(sliderAudioQuality->maximum()-sliderAudioQuality->minimum())/(suggestedMaxAudioQuality-suggestedMinAudioQuality)));
150 int sliderValueAudioQuality = lineEditValueToScaledSliderValue(lineEditValueAudioQuality, audioQuality);
151 sliderAudioQuality->setValue(sliderValueAudioQuality);
153 connect(sliderAudioQuality, &QSlider::valueChanged,
this,
static_cast<void (
VuoInputEditorMovieFormat::*)(
int)
>(&VuoInputEditorMovieFormat::updateLineEditValue));
154 connect(lineEditAudioQuality, &QLineEdit::textEdited,
this, &VuoInputEditorMovieFormat::updateSliderValue);
155 connect(lineEditAudioQuality, &QLineEdit::editingFinished,
this, &VuoInputEditorMovieFormat::emitValueChanged);
160 const int widgetVerticalSpacing = 4;
161 const int widgetHorizontalSpacing = 5;
164 const int comboLabelVerticalCorrection = 3;
165 const int lineEditLabelVerticalCorrection = 1;
167 QLabel *labelImageEncoding =
new QLabel(
"Image Encoding", &dialog);
168 QLabel *labelAudioEncoding =
new QLabel(
"Audio Encoding", &dialog);
169 labelImageQuality =
new QLabel(
"Image Quality", &dialog);
170 labelAudioQuality =
new QLabel(
"Audio Quality", &dialog);
175 updateQualitySliderEnabledStatus();
177 labelImageEncoding->move( labelImageEncoding->pos().x(),
178 labelImageEncoding->pos().y() + comboLabelVerticalCorrection);
179 comboBoxImageEncoding->move(labelImageEncoding->pos().x()+labelImageEncoding->width() + widgetHorizontalSpacing,
180 labelImageEncoding->pos().y() - comboLabelVerticalCorrection);
182 labelImageQuality->move( labelImageEncoding->pos().x(),
183 comboBoxImageEncoding->pos().y() + comboBoxImageEncoding->height() + widgetVerticalSpacing + lineEditLabelVerticalCorrection);
184 lineEditImageQuality->move( comboBoxImageEncoding->pos().x(),
185 labelImageQuality->pos().y() - lineEditLabelVerticalCorrection);
186 sliderImageQuality->move( lineEditImageQuality->pos().x(),
187 lineEditImageQuality->pos().y() + lineEditImageQuality->height() + widgetVerticalSpacing - lineEditLabelVerticalCorrection);
189 sliderImageQuality->resize(sliderImageQuality->width(), sliderImageQuality->height() - 10);
190 lineEditImageQuality->resize(sliderImageQuality->width(), lineEditImageQuality->height());
192 labelAudioEncoding->move( labelImageQuality->pos().x(),
193 sliderImageQuality->pos().y() + sliderImageQuality->height() + widgetVerticalSpacing + comboLabelVerticalCorrection);
194 comboBoxAudioEncoding->move(labelAudioEncoding->pos().x() + labelAudioEncoding->width() + widgetHorizontalSpacing,
195 labelAudioEncoding->pos().y() - comboLabelVerticalCorrection);
198 labelAudioQuality->move( labelAudioEncoding->pos().x(),
199 comboBoxAudioEncoding->pos().y() + comboBoxAudioEncoding->height() + widgetVerticalSpacing + lineEditLabelVerticalCorrection);
200 lineEditAudioQuality->move( comboBoxAudioEncoding->pos().x(),
201 labelAudioQuality->pos().y() - lineEditLabelVerticalCorrection);
202 sliderAudioQuality->move( lineEditAudioQuality->pos().x(),
203 lineEditAudioQuality->pos().y() + lineEditAudioQuality->height() + widgetVerticalSpacing - lineEditLabelVerticalCorrection);
205 sliderAudioQuality->resize(sliderAudioQuality->width(), sliderAudioQuality->height() - 10);
206 lineEditAudioQuality->resize(sliderAudioQuality->width(), lineEditAudioQuality->height());
208 labelImageEncoding->show();
209 comboBoxImageEncoding->show();
211 labelImageQuality->show();
212 sliderImageQuality->show();
214 labelAudioEncoding->show();
215 comboBoxAudioEncoding->show();
217 labelAudioQuality->show();
218 sliderAudioQuality->show();
230 lineEditImageQuality->text(),
231 comboBoxAudioEncoding->currentData(),
232 lineEditAudioQuality->text());
241 QString valueAsStringInUserLocale = QLocale().toString(realValue);
243 if (qAbs(realValue) >= 1000.0)
244 valueAsStringInUserLocale.remove(QLocale().groupSeparator());
246 return valueAsStringInUserLocale;
253 const QString &imageQualityAsString,
254 const QVariant &audioEncoding,
255 const QString &audioQualityAsString)
260 format.
imageQuality = QLocale().toDouble(imageQualityAsString);
261 format.
audioQuality = QLocale().toDouble(audioQualityAsString);
269void VuoInputEditorMovieFormat::updateSliderValue(QString newLineEditText)
271 QObject *sender = QObject::sender();
272 qualityAttribute whichQualityAttribute = (sender == lineEditImageQuality? imageQuality : audioQuality);
274 double newLineEditValue = QLocale().toDouble(newLineEditText);
275 int newSliderValue = lineEditValueToScaledSliderValue(newLineEditValue, whichQualityAttribute);
277 QSlider *targetSlider = (whichQualityAttribute == imageQuality? sliderImageQuality : sliderAudioQuality);
279 disconnect(targetSlider, &QSlider::valueChanged,
this,
static_cast<void (
VuoInputEditorMovieFormat::*)(
int)
>(&VuoInputEditorMovieFormat::updateLineEditValue));
280 targetSlider->setValue(newSliderValue);
281 connect(targetSlider, &QSlider::valueChanged,
this,
static_cast<void (
VuoInputEditorMovieFormat::*)(
int)
>(&VuoInputEditorMovieFormat::updateLineEditValue));
290void VuoInputEditorMovieFormat::updateLineEditValue()
292 QObject *sender = QObject::sender();
293 qualityAttribute whichQualityAttribute = (sender == sliderImageQuality? imageQuality: audioQuality);
294 updateLineEditValue(((QSlider *)sender)->value(), whichQualityAttribute);
297void VuoInputEditorMovieFormat::updateLineEditValue(
int newSliderValue)
299 QObject *sender = QObject::sender();
300 qualityAttribute whichQualityAttribute = (sender == sliderImageQuality? imageQuality: audioQuality);
302 updateLineEditValue(newSliderValue, whichQualityAttribute);
314void VuoInputEditorMovieFormat::updateLineEditValue(
int newSliderValue, qualityAttribute whichQualityAttribute)
316 double newLineEditValue = sliderValueToScaledLineEditValue(newSliderValue, whichQualityAttribute);
317 QLineEdit *targetLineEdit = (whichQualityAttribute == imageQuality? lineEditImageQuality : lineEditAudioQuality);
318 const QString originalLineEditText = targetLineEdit->text();
319 QString newLineEditText = QLocale().toString(newLineEditValue,
'g');
321 if (qAbs(newLineEditValue) >= 1000.0)
322 newLineEditText.remove(QLocale().groupSeparator());
324 if (originalLineEditText != newLineEditText)
326 targetLineEdit->setText(newLineEditText);
327 targetLineEdit->setFocus();
328 targetLineEdit->selectAll();
337int VuoInputEditorMovieFormat::lineEditValueToScaledSliderValue(
double lineEditValue, qualityAttribute whichQualityAttribute)
339 QSlider *targetSlider = (whichQualityAttribute == imageQuality? sliderImageQuality : sliderAudioQuality);
340 double suggestedMin = (whichQualityAttribute == imageQuality? suggestedMinImageQuality : suggestedMinAudioQuality);
341 double suggestedMax = (whichQualityAttribute == imageQuality? suggestedMaxImageQuality : suggestedMaxAudioQuality);
342 const double lineEditRange = suggestedMax - suggestedMin;
344 const int sliderRange = targetSlider->maximum() - targetSlider->minimum();
345 int scaledSliderValue = targetSlider->minimum() + ((lineEditValue-suggestedMin)/(1.0*(lineEditRange)))*sliderRange;
347 return scaledSliderValue;
354double VuoInputEditorMovieFormat::sliderValueToScaledLineEditValue(
int sliderValue, qualityAttribute whichQualityAttribute)
356 QSlider *targetSlider = (whichQualityAttribute == imageQuality? sliderImageQuality : sliderAudioQuality);
357 double suggestedMin = (whichQualityAttribute == imageQuality? suggestedMinImageQuality : suggestedMinAudioQuality);
358 double suggestedMax = (whichQualityAttribute == imageQuality? suggestedMaxImageQuality : suggestedMaxAudioQuality);
359 const double lineEditRange = suggestedMax - suggestedMin;
361 const int sliderRange = targetSlider->maximum() - targetSlider->minimum();
362 double scaledLineEditValue = suggestedMin + ((sliderValue-targetSlider->minimum())/(1.0*sliderRange))*lineEditRange;
364 return scaledLineEditValue;
367void VuoInputEditorMovieFormat::updateQualitySliderEnabledStatusAndEmitValueChanged()
369 updateQualitySliderEnabledStatus();
376void VuoInputEditorMovieFormat::updateQualitySliderEnabledStatus()
381 bool enableImageQualityWidgets = ((acceptedFormat.
imageEncoding == VuoMovieImageEncoding_JPEG) ||
382 (acceptedFormat.
imageEncoding == VuoMovieImageEncoding_H264) ||
383 (acceptedFormat.
imageEncoding == VuoMovieImageEncoding_HEVC) ||
384 (acceptedFormat.
imageEncoding == VuoMovieImageEncoding_HEVCAlpha));
386 labelImageQuality->setEnabled(enableImageQualityWidgets);
387 lineEditImageQuality->setEnabled(enableImageQualityWidgets);
388 sliderImageQuality->setEnabled(enableImageQualityWidgets);
390 if (!enableImageQualityWidgets)
392 int sliderValueImageQuality = lineEditValueToScaledSliderValue(1., imageQuality);
393 sliderImageQuality->setValue(sliderValueImageQuality);
397 bool enableAudioQualityWidgets = (acceptedFormat.
audioEncoding != VuoAudioEncoding_LinearPCM);
399 labelAudioQuality->setEnabled(enableAudioQualityWidgets);
400 lineEditAudioQuality->setEnabled(enableAudioQualityWidgets);
401 sliderAudioQuality->setEnabled(enableAudioQualityWidgets);
403 if (!enableAudioQualityWidgets)
405 int sliderValueAudioQuality = lineEditValueToScaledSliderValue(1., audioQuality);
406 sliderAudioQuality->setValue(sliderValueAudioQuality);
409 QLineEdit *firstEnabledLineEdit = (enableImageQualityWidgets? lineEditImageQuality :
410 (enableAudioQualityWidgets? lineEditAudioQuality :
413 QLineEdit *lastEnabledLineEdit = (enableAudioQualityWidgets? lineEditAudioQuality :
414 (enableImageQualityWidgets? lineEditImageQuality :
420 if (tabCycleForward && firstEnabledLineEdit)
422 firstEnabledLineEdit->setFocus();
423 firstEnabledLineEdit->selectAll();
425 else if (!tabCycleForward && lastEnabledLineEdit)
427 lastEnabledLineEdit->setFocus();
428 lastEnabledLineEdit->selectAll();
435void VuoInputEditorMovieFormat::emitValueChanged()
445 QSlider *targetSlider = (
object==lineEditImageQuality? sliderImageQuality :
446 (
object==lineEditAudioQuality? sliderAudioQuality :
449 if (event->type()==QEvent::Wheel && targetSlider)
452 QApplication::sendEvent(targetSlider, event);
456 else if (event->type()==QEvent::KeyPress && targetSlider)
459 QKeyEvent *keyEvent = (QKeyEvent *)(event);
460 if ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))
462 QApplication::sendEvent(targetSlider, event);
476QComboBox * VuoInputEditorMovieFormat::setUpComboBoxForType(QComboBox *comboBox, QString type,
string originalValueAsString)
478 QString allowedValuesFunctionName = type +
"_getAllowedValues";
479 typedef void *(*allowedValuesFunctionType)(void);
480 allowedValuesFunctionType allowedValuesFunction = (allowedValuesFunctionType)dlsym(RTLD_SELF, allowedValuesFunctionName.toUtf8().constData());
482 QString summaryFunctionName = type +
"_getSummary";
483 typedef char *(*summaryFunctionType)(int);
484 summaryFunctionType summaryFunction = (summaryFunctionType)dlsym(RTLD_SELF, summaryFunctionName.toUtf8().constData());
486 QString jsonFunctionName = type +
"_getJson";
488 jsonFunctionType jsonFunction = (jsonFunctionType)dlsym(RTLD_SELF, jsonFunctionName.toUtf8().constData());
490 QString listCountFunctionName =
"VuoListGetCount_" + type;
491 typedef unsigned long (*listCountFunctionType)(
void *);
492 listCountFunctionType listCountFunction = (listCountFunctionType)dlsym(RTLD_SELF, listCountFunctionName.toUtf8().constData());
494 QString listValueFunctionName =
"VuoListGetValue_" + type;
495 typedef int (*listValueFunctionType)(
void *,
unsigned long);
496 listValueFunctionType listValueFunction = (listValueFunctionType)dlsym(RTLD_SELF, listValueFunctionName.toUtf8().constData());
498 if (allowedValuesFunction && summaryFunction && jsonFunction && listCountFunction && listValueFunction)
500 void *allowedValues = allowedValuesFunction();
501 unsigned long count = listCountFunction(allowedValues);
502 for (
unsigned long i=1; i<=count; ++i)
504 int value = listValueFunction(allowedValues, i);
505 char *summary = summaryFunction(value);
506 QVariant variantValue = QVariant::fromValue(jsonFunction(value));
509 if (type ==
"VuoMovieImageEncoding"
510 && value == VuoMovieImageEncoding_HEVC
511 && QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSHighSierra)
516 if (type ==
"VuoMovieImageEncoding"
517 && (value == VuoMovieImageEncoding_HEVCAlpha
518 || value == VuoMovieImageEncoding_ProRes422HQ
519 || value == VuoMovieImageEncoding_ProRes422LT
520 || value == VuoMovieImageEncoding_ProRes422Proxy)
521 && QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSCatalina)
527 comboBox->addItem(summary, variantValue);
529 if (json_object_to_json_string_ext(jsonFunction(value), JSON_C_TO_STRING_PLAIN) == originalValueAsString)
530 comboBox->setCurrentText(summary);