Files
oak-editor/app/widget/standardcombos/pixelaspectratiocombobox.h
T
Mike-Solar 0aa5879f35 app: migrate all engine access to the C ABI facade (nm U _ZN5olive = 0)
Every app module now reaches liboakengine exclusively through
oakengine_* C calls, EngineEventBridge subscriptions and app-side
handle headers (cliphandle/keyframehandle/nodevaluehandle/oakvaluehelper).
Direct C++ command construction, engine signal connect()s, and engine
type usage in MOC-visible signatures are gone: 557 -> 0 undefined
olive:: symbols in oak-editor.
2026-07-26 22:43:21 +08:00

135 lines
3.7 KiB
C++

/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
Modifications Copyright (C) 2025 mikesolar
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef OAK_PIXELASPECTRATIOCOMBOBOX_H
#define OAK_PIXELASPECTRATIOCOMBOBOX_H
#include <QComboBox>
#include "dialog/ratiodialog.h"
#include "oakengine/videoparams.h"
namespace olive
{
class PixelAspectRatioComboBox : public QComboBox {
Q_OBJECT
public:
PixelAspectRatioComboBox(QWidget *parent = nullptr)
: QComboBox(parent)
, dont_prompt_custom_par_(false)
{
const int n = oakengine_video_params_standard_pixel_aspect_count();
for (int i = 0; i < n; i++) {
int num, den;
oakengine_video_params_standard_pixel_aspect_at(i, &num, &den);
char name_buf[256];
oakengine_video_params_standard_pixel_aspect_name(i, name_buf,
sizeof(name_buf));
Rational ratio(num, den);
this->addItem(QString::fromUtf8(name_buf),
QVariant::fromValue(ratio));
}
// Always add custom item last, much of the logic relies on this. Set this to the current AR so
// that if none of the above are ==, it will eventually select this item
this->addItem(QString());
update_custom_item(Rational());
// Pick up index signal to query for custom aspect ratio if requested
connect(this,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
this, &PixelAspectRatioComboBox::index_changed);
}
Rational get_pixel_aspect_ratio() const
{
return this->currentData().value<Rational>();
}
void set_pixel_aspect_ratio(const Rational &r)
{
// Determine which index to select on startup
for (int i = 0; i < this->count(); i++) {
if (this->itemData(i).value<Rational>() == r) {
this->setCurrentIndex(i);
return;
}
}
// Must not have found the ratio, so it must be custom
update_custom_item(r);
dont_prompt_custom_par_ = true;
this->setCurrentIndex(this->count() - 1);
dont_prompt_custom_par_ = false;
}
private slots:
void index_changed(int index)
{
if (dont_prompt_custom_par_) {
return;
}
// Detect if custom was selected, in which case query what the new AR should be
if (index == this->count() - 1) {
// Query for custom pixel aspect ratio
bool ok;
double custom_ratio = get_float_ratio_from_user(
this, tr("Set Custom Pixel Aspect Ratio"), &ok);
if (ok) {
update_custom_item(Rational::from_double(custom_ratio));
}
}
}
private:
void update_custom_item(const Rational &ratio)
{
const int custom_index = this->count() - 1;
if (ratio.isNull()) {
this->setItemText(custom_index, tr("Custom..."));
// Use 1:1 to prevent any real chance of the PAR being set to 0
this->setItemData(custom_index, QVariant::fromValue(Rational(1)));
} else {
char buf[256];
oakengine_video_params_format_pixel_aspect_ratio_string(
"%1", ratio.numerator(), ratio.denominator(), buf,
sizeof(buf));
this->setItemText(
custom_index,
tr("Custom (%1)").arg(QString::fromUtf8(buf)));
this->setItemData(custom_index, QVariant::fromValue(ratio));
}
}
bool dont_prompt_custom_par_;
};
}
#endif // OAK_PIXELASPECTRATIOCOMBOBOX_H