From 1915925dc86869ea7806e6adea5bea9266a1d115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole-Andr=C3=A9=20Rodlie?= Date: Fri, 6 Sep 2024 22:19:43 +0200 Subject: [PATCH] Renderer UI: add support for format options "good enough". --- .../RenderWidgets/outputsettingsdialog.cpp | 142 ++++++++++++++++++ .../GUI/RenderWidgets/outputsettingsdialog.h | 12 ++ 2 files changed, 154 insertions(+) diff --git a/src/app/GUI/RenderWidgets/outputsettingsdialog.cpp b/src/app/GUI/RenderWidgets/outputsettingsdialog.cpp index 4fd8138b7..f368f672b 100644 --- a/src/app/GUI/RenderWidgets/outputsettingsdialog.cpp +++ b/src/app/GUI/RenderWidgets/outputsettingsdialog.cpp @@ -27,6 +27,7 @@ #include "GUI/mainwindow.h" #include "GUI/global.h" #include "appsupport.h" +#include "formatoptions.h" OutputSettingsDialog::OutputSettingsDialog(const OutputSettings &settings, QWidget *parent) : @@ -162,11 +163,16 @@ OutputSettingsDialog::OutputSettingsDialog(const OutputSettings &settings, eSizesUI::widget.addSpacing(mMainLayout); mVideoGroupBox->setLayout(mVideoSettingsLayout); mMainLayout->addWidget(mVideoGroupBox); + + mFormatOptionsTree = new QTreeWidget(this); + setupFormatOptionsTree(); + mAudioGroupBox->setLayout(mAudioSettingsLayout); mMainLayout->addWidget(mAudioGroupBox); eSizesUI::widget.addSpacing(mMainLayout); mMainLayout->addLayout(mShowLayout); eSizesUI::widget.addSpacing(mMainLayout); + mMainLayout->addStretch(); mMainLayout->addLayout(mButtonsLayout); connect(mVideoCodecsComboBox, &QComboBox::currentTextChanged, [this]() { @@ -211,6 +217,7 @@ OutputSettings OutputSettingsDialog::getSettings() { settings.fVideoPixelFormat = currentPixelFormat; settings.fVideoBitrate = qRound(mBitrateSpinBox->value()*1000000); settings.fVideoProfile = mVideoProfileComboBox->currentData().toInt(); + settings.fVideoOptions = getFormatOptions(); settings.fAudioEnabled = mAudioGroupBox->isChecked(); const AVCodec *currentAudioCodec = nullptr; @@ -309,6 +316,139 @@ void OutputSettingsDialog::updateAvailableCodecs() { updateAvailableVideoCodecs(); } +void OutputSettingsDialog::setupFormatOptionsTree() +{ + const auto area = new QScrollArea(this); + const auto container = new QWidget(this); + const auto containerLayout = new QVBoxLayout(container); + const auto containerInner = new QWidget(this); + const auto containerInnerLayout = new QVBoxLayout(containerInner); + + area->setWidget(containerInner); + area->setWidgetResizable(true); + area->setContentsMargins(0, 0, 0, 0); + area->setFrameShape(QFrame::NoFrame); + + container->setContentsMargins(10, 0, 10, 0); + container->setMinimumHeight(150); + containerLayout->setMargin(0); + containerLayout->addWidget(area); + + containerInner->setContentsMargins(0, 0, 0, 0); + containerInnerLayout->setMargin(0); + + mFormatOptionsTree->setHeaderLabels(QStringList() + << tr("Type") + << tr("Key") + << tr("Value")); + mFormatOptionsTree->setTabKeyNavigation(true); + mFormatOptionsTree->setAlternatingRowColors(true); + mFormatOptionsTree->setSortingEnabled(false); + mFormatOptionsTree->setHeaderHidden(false); + mFormatOptionsTree->setRootIsDecorated(false); + mFormatOptionsTree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + const auto mPushButtonAddFOpt = new QPushButton(QIcon::fromTheme("plus"), + QString(), + this); + const auto mPushButtonRemFOpt = new QPushButton(QIcon::fromTheme("minus"), + QString(), + this); + + mPushButtonAddFOpt->setObjectName("FlatButton"); + mPushButtonAddFOpt->setFocusPolicy(Qt::NoFocus); + mPushButtonRemFOpt->setObjectName("FlatButton"); + mPushButtonRemFOpt->setFocusPolicy(Qt::NoFocus); + + connect(mPushButtonAddFOpt, &QPushButton::pressed, this, [this]() { + QTreeWidgetItem *item = new QTreeWidgetItem(mFormatOptionsTree); + item->setFlags(item->flags() | Qt::ItemIsEditable); + mFormatOptionsTree->addTopLevelItem(item); + mFormatOptionsTree->setItemWidget(item, 0, + createComboBoxFormatOptType()); + }); + connect(mPushButtonRemFOpt, &QPushButton::pressed, this, [this]() { + auto item = mFormatOptionsTree->selectedItems().count() > 0 ? + mFormatOptionsTree->selectedItems().at(0) : nullptr; + if (!item) { return; } + delete mFormatOptionsTree->takeTopLevelItem( + mFormatOptionsTree->indexOfTopLevelItem(item)); + }); + + mFormatOptionsTree->addScrollBarWidget(mPushButtonRemFOpt, + Qt::AlignBottom); + mFormatOptionsTree->addScrollBarWidget(mPushButtonAddFOpt, + Qt::AlignBottom); + + containerInnerLayout->addWidget(mFormatOptionsTree); + + const auto showHideWidget = new QWidget(this); + const auto showHideLayout = new QHBoxLayout(showHideWidget); + const auto showHideButton = new QPushButton(QIcon::fromTheme("go-down"), + tr("Advanced Options"), + this); + + showHideButton->setCheckable(true); + showHideButton->setFocusPolicy(Qt::NoFocus); + connect(showHideButton, &QPushButton::released, + this, [container, showHideButton]() { + container->setVisible(showHideButton->isChecked()); + showHideButton->setIcon(showHideButton->isChecked() ? + QIcon::fromTheme("go-up") : + QIcon::fromTheme("go-down")); + }); + + showHideWidget->setContentsMargins(0, 0, 10, 0); + showHideLayout->setMargin(0); + showHideLayout->addStretch(); + showHideLayout->addWidget(showHideButton); + + container->setVisible(false); + mMainLayout->addWidget(showHideWidget); + mMainLayout->addWidget(container); +} + +void OutputSettingsDialog::populateFormatOptionsTree(const FormatOptions &options) +{ + mFormatOptionsTree->clear(); + for (const auto &option : options.fValues) { + if (option.fKey.isEmpty()) { continue; } + QTreeWidgetItem *item = new QTreeWidgetItem(mFormatOptionsTree); + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setText(1, option.fKey); + item->setText(2, option.fValue); + auto combo = createComboBoxFormatOptType(option.fType); + mFormatOptionsTree->addTopLevelItem(item); + mFormatOptionsTree->setItemWidget(item, 0, combo); + } +} + +QComboBox *OutputSettingsDialog::createComboBoxFormatOptType(int selected) +{ + auto box = new QComboBox(mFormatOptionsTree); + box->addItem(tr("Meta"), FormatType::fTypeMeta); + box->addItem(tr("Format"), FormatType::fTypeFormat); + box->addItem(tr("Codec"), FormatType::fTypeCodec); + box->setCurrentIndex(selected); + return box; +} + +FormatOptions OutputSettingsDialog::getFormatOptions() +{ + FormatOptions options; + for (int i = 0; i < mFormatOptionsTree->topLevelItemCount(); i++) { + const auto item = mFormatOptionsTree->topLevelItem(i); + const auto combo = qobject_cast(mFormatOptionsTree->itemWidget(item, 0)); + if (!combo) { continue; } + const auto key = item->text(1); + const auto val = item->text(2); + if (key.isEmpty()) { continue; } + options.fValues.push_back({key, val, + combo->currentData().toInt()}); + } + return options; +} + void OutputSettingsDialog::updateAvailableVideoCodecs() { const QString currentCodecName = mVideoCodecsComboBox->currentText(); mVideoCodecsComboBox->clear(); @@ -749,6 +889,8 @@ void OutputSettingsDialog::restoreInitialSettings() { const bool noAudioCodecs = mAudioCodecsComboBox->count() == 0; mAudioGroupBox->setChecked(mInitialSettings.fAudioEnabled && !noAudioCodecs); + + populateFormatOptionsTree(mInitialSettings.fVideoOptions); } void OutputSettingsDialog::restoreVideoProfileSettings() diff --git a/src/app/GUI/RenderWidgets/outputsettingsdialog.h b/src/app/GUI/RenderWidgets/outputsettingsdialog.h index 4149426b6..1b91edc0e 100644 --- a/src/app/GUI/RenderWidgets/outputsettingsdialog.h +++ b/src/app/GUI/RenderWidgets/outputsettingsdialog.h @@ -25,6 +25,7 @@ #ifndef OUTPUTSETTINGSDIALOG_H #define OUTPUTSETTINGSDIALOG_H + #include #include #include @@ -33,8 +34,12 @@ #include #include #include +#include +#include + #include "renderinstancesettings.h" #include "widgets/twocolumnlayout.h" + #define COMPLIENCE FF_COMPLIANCE_NORMAL class OutputSettingsDialog : public QDialog { @@ -125,6 +130,13 @@ class OutputSettingsDialog : public QDialog { QPushButton *mOkButton = nullptr; QPushButton *mCancelButton = nullptr; QPushButton *mResetButton = nullptr; + + QTreeWidget *mFormatOptionsTree; + void setupFormatOptionsTree(); + void populateFormatOptionsTree(const FormatOptions &options); + QComboBox *createComboBoxFormatOptType(int selected = FormatType::fTypeMeta); + FormatOptions getFormatOptions(); + void addVideoCodec(const AVCodec * const codec, const AVOutputFormat *outputFormat, const QString ¤tCodecName);