Make video zoom different from preview window zoom
This commit is contained in:
parent
70ddf3c7f5
commit
4f6836da9c
5 changed files with 74 additions and 48 deletions
|
@ -669,7 +669,7 @@ public:
|
|||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->videoController->Stop();
|
||||
c->videoDisplay->SetZoom(1.);
|
||||
c->videoDisplay->SetWindowZoom(1.);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -700,7 +700,7 @@ public:
|
|||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->videoController->Stop();
|
||||
c->videoDisplay->SetZoom(2.);
|
||||
c->videoDisplay->SetWindowZoom(2.);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -718,7 +718,7 @@ public:
|
|||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->videoController->Stop();
|
||||
c->videoDisplay->SetZoom(.5);
|
||||
c->videoDisplay->SetWindowZoom(.5);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -730,7 +730,7 @@ struct video_zoom_in final : public validator_video_attached {
|
|||
STR_HELP("Zoom video in")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->videoDisplay->SetZoom(c->videoDisplay->GetZoom() + .125);
|
||||
c->videoDisplay->SetWindowZoom(c->videoDisplay->GetZoom() + .125);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -742,7 +742,7 @@ struct video_zoom_out final : public validator_video_attached {
|
|||
STR_HELP("Zoom video out")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->videoDisplay->SetZoom(c->videoDisplay->GetZoom() - .125);
|
||||
c->videoDisplay->SetWindowZoom(c->videoDisplay->GetZoom() - .125);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -276,9 +276,9 @@ void FrameMain::OnVideoOpen(AsyncVideoProvider *provider) {
|
|||
double zoom = context->videoDisplay->GetZoom();
|
||||
wxSize windowSize = GetSize();
|
||||
if (vidx*3*zoom > windowSize.GetX()*4 || vidy*4*zoom > windowSize.GetY()*6)
|
||||
context->videoDisplay->SetZoom(zoom * .25);
|
||||
context->videoDisplay->SetWindowZoom(zoom * .25);
|
||||
else if (vidx*3*zoom > windowSize.GetX()*2 || vidy*4*zoom > windowSize.GetY()*3)
|
||||
context->videoDisplay->SetZoom(zoom * .5);
|
||||
context->videoDisplay->SetWindowZoom(zoom * .5);
|
||||
|
||||
SetDisplayMode(1,-1);
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ void Project::LoadUnloadFiles(ProjectProperties properties) {
|
|||
vc->SetAspectRatio(properties.ar_value);
|
||||
else
|
||||
vc->SetAspectRatio(ar_mode);
|
||||
context->videoDisplay->SetZoom(properties.video_zoom);
|
||||
context->videoDisplay->SetWindowZoom(properties.video_zoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,19 +82,20 @@ VideoDisplay::VideoDisplay(wxToolBar *toolbar, bool freeSize, wxComboBox *zoomBo
|
|||
: wxGLCanvas(parent, -1, attribList)
|
||||
, autohideTools(OPT_GET("Tool/Visual/Autohide"))
|
||||
, con(c)
|
||||
, zoomValue(OPT_GET("Video/Default Zoom")->GetInt() * .125 + .125)
|
||||
, windowZoomValue(OPT_GET("Video/Default Zoom")->GetInt() * .125 + .125)
|
||||
, videoZoomValue(1)
|
||||
, toolBar(toolbar)
|
||||
, zoomBox(zoomBox)
|
||||
, freeSize(freeSize)
|
||||
, retina_helper(agi::make_unique<RetinaHelper>(this))
|
||||
, scale_factor(retina_helper->GetScaleFactor())
|
||||
, scale_factor_connection(retina_helper->AddScaleFactorListener([=](int new_scale_factor) {
|
||||
double new_zoom = zoomValue * new_scale_factor / scale_factor;
|
||||
double new_zoom = windowZoomValue * new_scale_factor / scale_factor;
|
||||
scale_factor = new_scale_factor;
|
||||
SetZoom(new_zoom);
|
||||
SetWindowZoom(new_zoom);
|
||||
}))
|
||||
{
|
||||
zoomBox->SetValue(fmt_wx("%g%%", zoomValue * 100.));
|
||||
zoomBox->SetValue(fmt_wx("%g%%", windowZoomValue * 100.));
|
||||
zoomBox->Bind(wxEVT_COMBOBOX, &VideoDisplay::SetZoomFromBox, this);
|
||||
zoomBox->Bind(wxEVT_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, this);
|
||||
|
||||
|
@ -193,11 +194,14 @@ void VideoDisplay::Render() try {
|
|||
PositionVideo();
|
||||
|
||||
videoOut->Render(viewport_left, viewport_bottom, viewport_width, viewport_height);
|
||||
E(glViewport(0, viewport_bottom_end, videoSize.GetWidth(), videoSize.GetHeight()));
|
||||
|
||||
int client_w, client_h;
|
||||
GetClientSize(&client_w, &client_h);
|
||||
E(glViewport(0, 0, client_w, client_h));
|
||||
|
||||
E(glMatrixMode(GL_PROJECTION));
|
||||
E(glLoadIdentity());
|
||||
E(glOrtho(0.0f, videoSize.GetWidth() / scale_factor, videoSize.GetHeight() / scale_factor, 0.0f, -1000.0f, 1000.0f));
|
||||
E(glOrtho(0.0f, client_w / scale_factor, client_h / scale_factor, 0.0f, -1000.0f, 1000.0f));
|
||||
|
||||
if (OPT_GET("Video/Overscan Mask")->GetBool()) {
|
||||
double ar = con->videoController->GetAspectRatioValue();
|
||||
|
@ -274,7 +278,7 @@ void VideoDisplay::PositionVideo() {
|
|||
GetClientSize(&client_w, &client_h);
|
||||
|
||||
viewport_left = 0;
|
||||
viewport_bottom_end = viewport_bottom = client_h * scale_factor - videoSize.GetHeight();
|
||||
viewport_bottom = client_h * scale_factor - videoSize.GetHeight();
|
||||
viewport_top = 0;
|
||||
viewport_width = videoSize.GetWidth();
|
||||
viewport_height = videoSize.GetHeight();
|
||||
|
@ -284,27 +288,26 @@ void VideoDisplay::PositionVideo() {
|
|||
int vidH = provider->GetHeight();
|
||||
|
||||
AspectRatio arType = con->videoController->GetAspectRatioType();
|
||||
double displayAr = double(viewport_width) / viewport_height;
|
||||
double displayAr = double(client_w) / client_h;
|
||||
double videoAr = arType == AspectRatio::Default ? double(vidW) / vidH : con->videoController->GetAspectRatioValue();
|
||||
|
||||
// Window is wider than video, blackbox left/right
|
||||
if (displayAr - videoAr > 0.01) {
|
||||
int delta = viewport_width - videoAr * viewport_height;
|
||||
int delta = client_w - videoAr * client_h;
|
||||
viewport_left = delta / 2;
|
||||
viewport_width -= delta;
|
||||
}
|
||||
// Video is wider than window, blackbox top/bottom
|
||||
else if (videoAr - displayAr > 0.01) {
|
||||
int delta = viewport_height - viewport_width / videoAr;
|
||||
int delta = client_h - client_w / videoAr;
|
||||
viewport_top = viewport_bottom = delta / 2;
|
||||
viewport_height -= delta;
|
||||
viewport_width = viewport_height * videoAr;
|
||||
}
|
||||
}
|
||||
|
||||
viewport_left += pan_x;
|
||||
viewport_top += pan_y;
|
||||
viewport_bottom -= pan_y;
|
||||
viewport_bottom_end = std::min(viewport_bottom_end, 0);
|
||||
|
||||
if (tool) {
|
||||
tool->SetClientSize(client_w * scale_factor, client_h * scale_factor);
|
||||
|
@ -319,9 +322,7 @@ void VideoDisplay::UpdateSize() {
|
|||
if (!provider || !IsShownOnScreen()) return;
|
||||
|
||||
videoSize.Set(provider->GetWidth(), provider->GetHeight());
|
||||
videoSize *= zoomValue;
|
||||
if (con->videoController->GetAspectRatioType() != AspectRatio::Default)
|
||||
videoSize.SetWidth(videoSize.GetHeight() * con->videoController->GetAspectRatioValue());
|
||||
videoSize *= videoZoomValue * windowZoomValue;
|
||||
|
||||
wxEventBlocker blocker(this);
|
||||
if (freeSize) {
|
||||
|
@ -329,13 +330,15 @@ void VideoDisplay::UpdateSize() {
|
|||
while (!top->IsTopLevel()) top = top->GetParent();
|
||||
|
||||
wxSize cs = GetClientSize();
|
||||
float csAr = (float)cs.GetWidth() / (float)cs.GetHeight();
|
||||
wxSize oldSize = top->GetSize();
|
||||
top->SetSize(top->GetSize() + videoSize / scale_factor - cs);
|
||||
top->SetSize(top->GetSize() + wxSize(provider->GetHeight() * csAr, provider->GetHeight()) * windowZoomValue / scale_factor - cs);
|
||||
SetClientSize(cs + top->GetSize() - oldSize);
|
||||
}
|
||||
else {
|
||||
SetMinClientSize(videoSize / scale_factor);
|
||||
SetMaxClientSize(videoSize / scale_factor);
|
||||
wxSize newSize = wxSize(provider->GetWidth(), provider->GetHeight()) * windowZoomValue / scale_factor;
|
||||
SetMinClientSize(newSize);
|
||||
SetMaxClientSize(newSize);
|
||||
|
||||
GetGrandParent()->Layout();
|
||||
}
|
||||
|
@ -345,11 +348,16 @@ void VideoDisplay::UpdateSize() {
|
|||
|
||||
void VideoDisplay::OnSizeEvent(wxSizeEvent &event) {
|
||||
if (freeSize) {
|
||||
videoSize = GetClientSize() * scale_factor;
|
||||
PositionVideo();
|
||||
zoomValue = double(viewport_height) / con->project->VideoProvider()->GetHeight();
|
||||
zoomBox->ChangeValue(fmt_wx("%g%%", zoomValue * 100.));
|
||||
con->ass->Properties.video_zoom = zoomValue;
|
||||
/* If the video is not moved */
|
||||
if (videoZoomValue == 1.0f && pan_x == 0 && pan_y == 0)
|
||||
videoSize = GetClientSize() * scale_factor;
|
||||
/* If the video is moving, we only need to update the size in this case */
|
||||
else if (videoSize.GetWidth() == 0 && videoSize.GetHeight() == 0)
|
||||
videoSize = GetClientSize() * videoZoomValue * scale_factor;
|
||||
windowZoomValue = double(GetClientSize().GetHeight()) / con->project->VideoProvider()->GetHeight();
|
||||
zoomBox->ChangeValue(fmt_wx("%g%%", windowZoomValue * 100.));
|
||||
con->ass->Properties.video_zoom = windowZoomValue;
|
||||
UpdateSize();
|
||||
}
|
||||
else {
|
||||
PositionVideo();
|
||||
|
@ -387,7 +395,10 @@ void VideoDisplay::OnMouseLeave(wxMouseEvent& event) {
|
|||
void VideoDisplay::OnMouseWheel(wxMouseEvent& event) {
|
||||
if (int wheel = event.GetWheelRotation()) {
|
||||
if (ForwardMouseWheelEvent(this, event))
|
||||
SetZoom(zoomValue + .125 * (wheel / event.GetWheelDelta()));
|
||||
if (event.ControlDown())
|
||||
SetWindowZoom(windowZoomValue + .125 * (wheel / event.GetWheelDelta()));
|
||||
else
|
||||
SetVideoZoom(videoZoomValue + .125 * (wheel / event.GetWheelDelta()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,28 +414,42 @@ void VideoDisplay::OnKeyDown(wxKeyEvent &event) {
|
|||
|
||||
void VideoDisplay::ResetPan() {
|
||||
pan_x = pan_y = 0;
|
||||
videoZoomValue = 1;
|
||||
UpdateSize();
|
||||
PositionVideo();
|
||||
}
|
||||
|
||||
void VideoDisplay::SetZoom(double value) {
|
||||
void VideoDisplay::SetWindowZoom(double value) {
|
||||
if (value == 0) return;
|
||||
value = std::max(value, .125);
|
||||
pan_x *= value / zoomValue;
|
||||
pan_y *= value / zoomValue;
|
||||
zoomValue = value;
|
||||
size_t selIndex = zoomValue / .125 - 1;
|
||||
pan_x *= value / windowZoomValue;
|
||||
pan_y *= value / windowZoomValue;
|
||||
windowZoomValue = value;
|
||||
size_t selIndex = windowZoomValue / .125 - 1;
|
||||
if (selIndex < zoomBox->GetCount())
|
||||
zoomBox->SetSelection(selIndex);
|
||||
zoomBox->ChangeValue(fmt_wx("%g%%", zoomValue * 100.));
|
||||
con->ass->Properties.video_zoom = zoomValue;
|
||||
zoomBox->ChangeValue(fmt_wx("%g%%", windowZoomValue * 100.));
|
||||
con->ass->Properties.video_zoom = windowZoomValue;
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void VideoDisplay::SetVideoZoom(double value) {
|
||||
if (value == 0) return;
|
||||
value = std::max(value, .125);
|
||||
Vector2D mp = tool->FromScriptCoords(GetMousePosition());
|
||||
wxSize cs = GetClientSize();
|
||||
pan_x *= value / videoZoomValue;
|
||||
pan_y *= value / videoZoomValue;
|
||||
|
||||
videoZoomValue = value;
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void VideoDisplay::SetZoomFromBox(wxCommandEvent &) {
|
||||
int sel = zoomBox->GetSelection();
|
||||
if (sel != wxNOT_FOUND) {
|
||||
zoomValue = (sel + 1) * .125;
|
||||
con->ass->Properties.video_zoom = zoomValue;
|
||||
windowZoomValue = (sel + 1) * .125;
|
||||
con->ass->Properties.video_zoom = windowZoomValue;
|
||||
UpdateSize();
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +461,7 @@ void VideoDisplay::SetZoomFromBoxText(wxCommandEvent &) {
|
|||
|
||||
double value;
|
||||
if (strValue.ToDouble(&value))
|
||||
SetZoom(value / 100.);
|
||||
SetWindowZoom(value / 100.);
|
||||
}
|
||||
|
||||
void VideoDisplay::SetTool(std::unique_ptr<VisualToolBase> new_tool) {
|
||||
|
|
|
@ -79,15 +79,15 @@ class VideoDisplay final : public wxGLCanvas {
|
|||
int viewport_width = 0;
|
||||
/// Screen pixels between the bottom of the canvas and the bottom of the video; used for glViewport
|
||||
int viewport_bottom = 0;
|
||||
/// The REAL bottom of the viewport; used only for glViewport
|
||||
int viewport_bottom_end = 0;
|
||||
/// Screen pixels between the bottom of the canvas and the top of the video; used for coordinate space conversion
|
||||
int viewport_top = 0;
|
||||
/// The height of the video in screen pixels
|
||||
int viewport_height = 0;
|
||||
|
||||
/// The current zoom level, where 1.0 = 100%
|
||||
double zoomValue;
|
||||
/// The current window zoom level, where 1.0 = 100%
|
||||
double windowZoomValue;
|
||||
/// The current video zoom level, where 1.0 = 100% relative to the display window size
|
||||
double videoZoomValue;
|
||||
|
||||
/// The last position of the mouse, when dragging
|
||||
Vector2D pan_last_pos;
|
||||
|
@ -167,9 +167,10 @@ public:
|
|||
|
||||
/// @brief Set the zoom level
|
||||
/// @param value The new zoom level
|
||||
void SetZoom(double value);
|
||||
void SetWindowZoom(double value);
|
||||
void SetVideoZoom(double value);
|
||||
/// @brief Get the current zoom level
|
||||
double GetZoom() const { return zoomValue; }
|
||||
double GetZoom() const { return windowZoomValue; }
|
||||
|
||||
/// @brief Reset the video pan
|
||||
void ResetPan();
|
||||
|
|
Loading…
Reference in a new issue