Fix mouse position bug when videoAr > displayAr

Crosshair drawing is broken when videoAr != displayAr
This commit is contained in:
moex3 2020-11-25 10:54:37 +01:00 committed by Sodra
parent 5f95f76671
commit 0ec0f20695
5 changed files with 22 additions and 11 deletions

View File

@ -193,7 +193,7 @@ void VideoDisplay::Render() try {
PositionVideo();
videoOut->Render(viewport_left, viewport_bottom, viewport_width, viewport_height);
E(glViewport(0, viewport_bottom, videoSize.GetWidth(), videoSize.GetHeight()));
E(glViewport(0, viewport_bottom_end, videoSize.GetWidth(), videoSize.GetHeight()));
E(glMatrixMode(GL_PROJECTION));
E(glLoadIdentity());
@ -270,8 +270,11 @@ void VideoDisplay::PositionVideo() {
auto provider = con->project->VideoProvider();
if (!provider || !IsShownOnScreen()) return;
int client_w, client_h;
GetClientSize(&client_w, &client_h);
viewport_left = 0;
viewport_bottom = GetClientSize().GetHeight() * scale_factor - videoSize.GetHeight();
viewport_bottom_end = viewport_bottom = client_h * scale_factor - videoSize.GetHeight();
viewport_top = 0;
viewport_width = videoSize.GetWidth();
viewport_height = videoSize.GetHeight();
@ -299,12 +302,15 @@ void VideoDisplay::PositionVideo() {
}
viewport_left += pan_x;
viewport_top += pan_y;
viewport_bottom -= pan_y;
viewport_bottom_end = std::min(viewport_bottom_end, 0);
if (tool)
if (tool) {
tool->SetClientSize(viewport_width, viewport_height);
tool->SetDisplayArea(viewport_left / scale_factor, viewport_top / scale_factor,
viewport_width / scale_factor, viewport_height / scale_factor);
}
Render();
}
@ -368,12 +374,9 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
PositionVideo();
}
if (tool) {
if (pan_y)
event.SetPosition(wxPoint(event.GetX(), event.GetY() - pan_y));
if (tool)
tool->OnMouseEvent(event);
}
}
void VideoDisplay::OnMouseLeave(wxMouseEvent& event) {
mouse_pos = Vector2D();

View File

@ -79,6 +79,8 @@ 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

View File

@ -132,6 +132,10 @@ AssDialogue* VisualToolBase::GetActiveDialogueLine() {
return nullptr;
}
void VisualToolBase::SetClientSize(int w, int h) {
client_size = Vector2D(w, h);
}
void VisualToolBase::SetDisplayArea(int x, int y, int w, int h) {
if (x == video_pos.X() && y == video_pos.Y() && w == video_res.X() && h == video_res.Y()) return;

View File

@ -104,6 +104,7 @@ protected:
Vector2D script_res; ///< Script resolution
Vector2D video_pos; ///< Top-left corner of the video in the display area
Vector2D video_res; ///< Video resolution
Vector2D client_size; ///< The size of the display area
const agi::OptionValue *highlight_color_primary_opt;
const agi::OptionValue *highlight_color_secondary_opt;
@ -144,6 +145,7 @@ public:
// Stuff called by VideoDisplay
virtual void OnMouseEvent(wxMouseEvent &event)=0;
virtual void Draw()=0;
virtual void SetClientSize(int w, int h);
virtual void SetDisplayArea(int x, int y, int w, int h);
virtual void SetToolbar(wxToolBar *) { }
virtual ~VisualToolBase() = default;

View File

@ -69,10 +69,10 @@ void VisualToolCross::Draw() {
gl.SetInvert();
gl.SetLineColour(*wxWHITE, 1.0, 1);
float lines[] = {
video_pos.X(), mouse_pos.Y(),
video_res.X() + video_pos.X(), mouse_pos.Y(),
0.f, mouse_pos.Y(),
client_size.X(), mouse_pos.Y(),
mouse_pos.X(), 0.f,
mouse_pos.X(), video_res.Y() + video_pos.Y() * 2
mouse_pos.X(), client_size.Y(),
};
gl.DrawLines(2, lines, 4);
gl.ClearInvert();