Skip to content

Commit

Permalink
ViewerWindow: add basic bits of scale-to-fit view mode
Browse files Browse the repository at this point in the history
- geting correct factor for scaled view
- implementing scaling logic
- implementing centering logic
- scaling input as well

TODO:
- 2nd viewerwindow does not setup mode correctly
- set mode should be remembered globally across restarts
  • Loading branch information
bk138 committed Apr 11, 2024
1 parent 20b8613 commit 7ab0ef6
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 13 deletions.
112 changes: 100 additions & 12 deletions src/gui/ViewerWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@


#include <wx/gdicmn.h>
#include <wx/log.h>
#include <wx/math.h>
#include <wx/sizer.h>
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
Expand Down Expand Up @@ -58,6 +61,7 @@ class VNCCanvas: public wxPanel

VNCConn* conn;
wxRegion updated_area;
double scale_factor = 1.0;
bool do_keyboard_grab;
};

Expand Down Expand Up @@ -169,14 +173,26 @@ void VNCCanvas::onUpdateTimer(wxTimerEvent& event)
while(upd)
{
wxRect update_rect(upd.GetRect());


if(scale_factor != 1.0) {
update_rect.x *= scale_factor;
update_rect.y *= scale_factor;
update_rect.width *= scale_factor;
update_rect.height *= scale_factor;

// fixes artifacts. +2 because double->int cuttofs can happen for x,y _and_ w,h scaling
update_rect.width += 2;
update_rect.height += 2;
}

wxLogDebug(wxT("VNCCanvas %p: invalidating updated rect: (%i,%i,%i,%i)"),
this,
update_rect.x,
update_rect.y,
update_rect.width,
update_rect.height);

// triggers onPaint()
Refresh(false, &update_rect);
++upd;
}
Expand All @@ -199,13 +215,32 @@ void VNCCanvas::onPaint(wxPaintEvent &WXUNUSED(event))
return;

wxPaintDC dc(this);
dc.SetUserScale(scale_factor, scale_factor);

// get the update rect list
wxRegionIterator upd(GetUpdateRegion());
while(upd)
{
wxRect update_rect(upd.GetRect());


if(scale_factor != 1.0) {
update_rect.x /= scale_factor;
update_rect.y /= scale_factor;
update_rect.width /= scale_factor;
update_rect.height /= scale_factor;

// fixes artifacts. +2 because double->int cuttofs can happen for x,y _and_ w,h scaling
update_rect.width += 2;
update_rect.height += 2;

// make sure this is always within the framebuffer boudaries;
// might not always be due to the artifact fix above, would not be drawn then
update_rect.Intersect(wxRect(0,
0,
conn->getFrameBufferWidth(),
conn->getFrameBufferHeight()));
}

wxLogDebug(wxT("VNCCanvas %p: got repaint event: (%i,%i,%i,%i)"),
this,
update_rect.x,
Expand Down Expand Up @@ -269,6 +304,10 @@ void VNCCanvas::onMouseAction(wxMouseEvent &event)
ungrab_keyboard();
}

// use rounding here to be a bit more correct if scaling causes fractional values
event.m_x = std::round(event.m_x / scale_factor);
event.m_y = std::round(event.m_y / scale_factor);

conn->sendPointerEvent(event);
}

Expand Down Expand Up @@ -337,6 +376,7 @@ void VNCCanvas::onFocusLoss(wxFocusEvent &event)
BEGIN_EVENT_TABLE(ViewerWindow, wxPanel)
EVT_TIMER (VIEWERWINDOW_STATS_TIMER_ID, ViewerWindow::onStatsTimer)
EVT_VNCCONNUPDATENOTIFY (wxID_ANY, ViewerWindow::onVNCConnUpdateNotify)
EVT_SIZE (ViewerWindow::onResize)
END_EVENT_TABLE()


Expand Down Expand Up @@ -516,7 +556,11 @@ void ViewerWindow::onStatsTimer(wxTimerEvent& event)
}
}


void ViewerWindow::onResize(wxSizeEvent &event)
{
wxLogDebug("ViewerWindow %p: resized to (%i, %i)", this, GetSize().GetWidth(), GetSize().GetHeight());
adjustCanvasSize();
}

/*
public members
Expand All @@ -527,15 +571,57 @@ void ViewerWindow::adjustCanvasSize()
{
if(canvas)
{
wxLogDebug(wxT("ViewerWindow %p: adjusting canvas size to (%i, %i)"),
this,
canvas->conn->getFrameBufferWidth(),
canvas->conn->getFrameBufferHeight());

// SetSize() isn't enough...
canvas->SetInitialSize(wxSize(canvas->conn->getFrameBufferWidth(), canvas->conn->getFrameBufferHeight()));
canvas->CentreOnParent();
Layout();
if(show_1to1) {
// reset scale factor
canvas->scale_factor = 1.0;
// and enable scroll bars
canvas_container->SetScrollRate(VIEWERWINDOW_SCROLL_RATE, VIEWERWINDOW_SCROLL_RATE);
} else {
/*
calculate scale factor
*/
wxLogDebug("ViewerWindow %p: adjustCanvasSize: framebuffer is %d x %d",
this,
canvas->conn->getFrameBufferWidth(),
canvas->conn->getFrameBufferHeight());
wxLogDebug("ViewerWindow %p: adjustCanvasSize: window is %d x %d",
this,
GetSize().GetWidth(),
GetSize().GetHeight());

float width_factor = GetSize().GetWidth() / (float)canvas->conn->getFrameBufferWidth();

// stats shown?
int stats_height = 0;
if(GetSizer()->IsShown(1)) {
// compute correct size for initial case
Layout();
stats_height = stats_container->GetSize().GetHeight();
}
float height_factor = (GetSize().GetHeight() - stats_height) / (float)canvas->conn->getFrameBufferHeight();

wxLogDebug("ViewerWindow %p: adjustCanvasSize: width factor is %f", this, width_factor);
wxLogDebug("ViewerWindow %p: adjustCanvasSize: height factor is %f", this, height_factor);

canvas->scale_factor = wxMin(width_factor, height_factor);

/*
and disable scroll bars
*/
canvas_container->SetScrollRate(0, 0);
}
wxSize dimensions(canvas->conn->getFrameBufferWidth() * canvas->scale_factor,
canvas->conn->getFrameBufferHeight() * canvas->scale_factor);

wxLogDebug(wxT("ViewerWindow %p: adjustCanvasSize: adjusting canvas size to (%i, %i)"),
this,
dimensions.GetWidth(),
dimensions.GetHeight());

// SetSize() isn't enough...
canvas->SetInitialSize(dimensions);
canvas->CentreOnParent();
Layout();
}
}

Expand All @@ -554,6 +640,7 @@ void ViewerWindow::showStats(bool show_stats)
stats_timer.Stop();
GetSizer()->Show(1, false);
}
adjustCanvasSize();
Layout();

text_ctrl_updrawbytes->Clear();
Expand All @@ -566,6 +653,7 @@ void ViewerWindow::showStats(bool show_stats)
void ViewerWindow::showOneToOne(bool show_1to1)
{
this->show_1to1 = show_1to1;
adjustCanvasSize();
}


Expand Down
2 changes: 1 addition & 1 deletion src/gui/ViewerWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ViewerWindow: public wxPanel
// timer to update stats win
wxTimer stats_timer;
void onStatsTimer(wxTimerEvent& event);

void onResize(wxSizeEvent &event);
void onVNCConnUpdateNotify(VNCConnUpdateNotifyEvent& event);

// save default foreground colour to be able to flash when buffer full
Expand Down

0 comments on commit 7ab0ef6

Please sign in to comment.