forked from mia/Aegisub
2bf23af00a
Most of the dialogs in Aegisub have a public interface consisting of a single function, so there's really no need to expose the actual dialog classes to the rest of the program. Add dialogs.h with the declarations of all of those functions (most of which are just ShowFooDialog()), and kill a million other headers.
161 lines
5.2 KiB
C++
161 lines
5.2 KiB
C++
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
|
|
//
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
//
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
#include "ass_file.h"
|
|
#include "async_video_provider.h"
|
|
#include "options.h"
|
|
#include "resolution_resampler.h"
|
|
|
|
#include <wx/dialog.h>
|
|
#include <wx/intl.h>
|
|
#include <wx/radiobox.h>
|
|
#include <wx/sizer.h>
|
|
#include <wx/stattext.h>
|
|
|
|
namespace {
|
|
enum {
|
|
MISMATCH_IGNORE,
|
|
MISMATCH_PROMPT,
|
|
MISMATCH_RESAMPLE,
|
|
MISMATCH_SET
|
|
};
|
|
enum {
|
|
FIX_IGNORE,
|
|
FIX_SET,
|
|
FIX_RESAMPLE
|
|
};
|
|
|
|
class Prompt : public wxDialog {
|
|
public:
|
|
Prompt(wxWindow *parent, bool ar_changed, int sx, int sy, int vx, int vy)
|
|
: wxDialog(parent, -1, _("Resolution mismatch"))
|
|
{
|
|
auto label_text = wxString::Format(_("The resolution of the loaded video and the resolution specified for the subtitles don't match.\n\nVideo resolution:\t%d x %d\nScript resolution:\t%d x %d\n\nChange subtitles resolution to match video?"), vx, vy, sx, sy);
|
|
|
|
auto sizer = new wxBoxSizer(wxVERTICAL);
|
|
sizer->Add(new wxStaticText(this, -1, label_text), wxSizerFlags().Border());
|
|
|
|
wxRadioBox *rb;
|
|
if (ar_changed) {
|
|
wxString choices[] = {
|
|
_("Set to video resolution"),
|
|
_("Resample script (stretch to new aspect ratio)"),
|
|
_("Resample script (add borders)"),
|
|
_("Resample script (remove borders)")
|
|
};
|
|
rb = new wxRadioBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 4, choices, 1);
|
|
}
|
|
else {
|
|
wxString choices[] = {
|
|
_("Set to video resolution"),
|
|
_("Resample script"),
|
|
};
|
|
rb = new wxRadioBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 2, choices, 1);
|
|
}
|
|
sizer->Add(rb, wxSizerFlags().Border(wxALL & ~wxTOP).Expand());
|
|
sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP), wxSizerFlags().Border().Expand());
|
|
|
|
unsigned int sel = OPT_GET("Video/Last Script Resolution Mismatch Choice")->GetInt();
|
|
rb->SetSelection(std::min(sel - 1, rb->GetCount()));
|
|
|
|
SetSizerAndFit(sizer);
|
|
CenterOnParent();
|
|
|
|
Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { EndModal(rb->GetSelection() + 1); }, wxID_OK);
|
|
Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { EndModal(0); }, wxID_CANCEL);
|
|
}
|
|
};
|
|
bool update_video_properties(AssFile *file, const AsyncVideoProvider *new_provider, wxWindow *parent) {
|
|
bool commit_subs = false;
|
|
|
|
// When opening dummy video only want to set the script properties if
|
|
// they were previously unset
|
|
bool set_properties = new_provider->ShouldSetVideoProperties();
|
|
|
|
auto matrix = new_provider->GetColorSpace();
|
|
if (set_properties && matrix != file->GetScriptInfo("YCbCr Matrix")) {
|
|
file->SetScriptInfo("YCbCr Matrix", matrix);
|
|
commit_subs = true;
|
|
}
|
|
|
|
// Check that the script resolution matches the video resolution
|
|
int sx = file->GetScriptInfoAsInt("PlayResX");
|
|
int sy = file->GetScriptInfoAsInt("PlayResY");
|
|
int vx = new_provider->GetWidth();
|
|
int vy = new_provider->GetHeight();
|
|
|
|
// If the script resolution hasn't been set at all just force it to the
|
|
// video resolution
|
|
if (sx == 0 && sy == 0) {
|
|
file->SetScriptInfo("PlayResX", std::to_string(vx));
|
|
file->SetScriptInfo("PlayResY", std::to_string(vy));
|
|
return true;
|
|
}
|
|
|
|
if (!set_properties)
|
|
return false;
|
|
|
|
// Treat exact multiples of the video resolution as equaling the resolution
|
|
// for the people who use that for subpixel precision (which is mostly
|
|
// pointless these days due to decimals being supported almost everywhere)
|
|
if (sx % vx == 0 && sy % vy == 0)
|
|
return commit_subs;
|
|
|
|
auto sar = double(sx) / sy;
|
|
auto var = double(vx) / vy;
|
|
bool ar_changed = abs(sar - var) / var > .01;
|
|
|
|
switch (OPT_GET("Video/Script Resolution Mismatch")->GetInt()) {
|
|
case MISMATCH_IGNORE: default:
|
|
return commit_subs;
|
|
|
|
case MISMATCH_SET:
|
|
file->SetScriptInfo("PlayResX", std::to_string(vx));
|
|
file->SetScriptInfo("PlayResY", std::to_string(vy));
|
|
return true;
|
|
|
|
case MISMATCH_RESAMPLE:
|
|
// Fallthrough to prompt if the AR changed
|
|
if (!ar_changed) {
|
|
ResampleResolution(file, {
|
|
{0, 0, 0, 0},
|
|
sx, sy, vx, vy,
|
|
ResampleARMode::Stretch,
|
|
YCbCrMatrix::rgb, YCbCrMatrix::rgb
|
|
});
|
|
return true;
|
|
}
|
|
|
|
case MISMATCH_PROMPT:
|
|
int res = Prompt(parent, ar_changed, sx, sy, vx, vy).ShowModal();
|
|
if (res == FIX_IGNORE) return commit_subs;
|
|
OPT_SET("Video/Last Script Resolution Mismatch Choice")->SetInt(res);
|
|
|
|
ResampleResolution(file, {
|
|
{0, 0, 0, 0},
|
|
sx, sy, vx, vy,
|
|
static_cast<ResampleARMode>(res - FIX_RESAMPLE),
|
|
YCbCrMatrix::rgb, YCbCrMatrix::rgb
|
|
});
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateVideoProperties(AssFile *file, const AsyncVideoProvider *new_provider, wxWindow *parent) {
|
|
if (update_video_properties(file, new_provider, parent))
|
|
file->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO);
|
|
}
|