From 3d48aa2992d8c9c20d6cf72065dc02fc07d3553b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan=20Fulea?= Date: Sat, 17 Nov 2018 00:05:51 +0200 Subject: [PATCH] [MSPAINT] Fix scrollbar presence on canvas/view fitting (#878) * [MSPAINT] Fix scrollbar presence on canvas/view fitting This is a small fix for a scrollbar related edge case functionality exhibited in mspaint (and in a lesser degree also elsewhere in instances of) scrollbar controlled content. As known, the scrollbars presence is given by the size ratio between the accommodating outer frame and the scroll-controlled contents inside it, and it works for the most part. There is, however, a case where the presence of both toolbars is kept even when the contents would fit the frame (if not for the scrollbars themselves that increase the size of the contents' area). Please take the current commit as a demo fix and a provisional correction for mspaint (as I think that the proper fix should reside in common controls). * [MSPAINT] Fix a small mistake and improve readability in UpdateScrollbox() Although with no visible impact on testing, I've used a wrong constant related to vertical scrollbox width in one instance (SM_CXHSCROLL instead of SM_CXVSCROLL), and this fixes it. Also, prefer using constants, to improve a bit readability and performance (by avoiding repeated function calls). --- base/applications/mspaint/scrollbox.cpp | 84 +++++++++++++++++++++---- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/base/applications/mspaint/scrollbox.cpp b/base/applications/mspaint/scrollbox.cpp index b0ef7373c78..351c59c717d 100644 --- a/base/applications/mspaint/scrollbox.cpp +++ b/base/applications/mspaint/scrollbox.cpp @@ -9,31 +9,89 @@ /* INCLUDES *********************************************************/ #include "precomp.h" +#include + +/* + * Scrollbar functional modes: + * 0 view < canvas + * 1 view < canvas + scroll width + * 2 view >= canvas + scroll width + * + * Matrix of scrollbar presence (VERTICAL,HORIZONTAL) given by + * vertical & horizontal scrollbar modes (view:canvas ratio): + * + * horizontal mode + * | 0 | 1 | 2 + * vertical ---+-------------+-------------+------------ + * mode 0 | TRUE,TRUE | TRUE,TRUE | TRUE,FALSE + * ---+-------------+-------------+------------ + * 1 | TRUE,TRUE | FALSE,FALSE | FALSE,FALSE + * ---+-------------+-------------+------------ + * 2 | FALSE,TRUE | FALSE,FALSE | FALSE,FALSE + */ + +struct ScrollbarPresence +{ + BOOL bVert; + BOOL bHoriz; +}; + +CONST ScrollbarPresence sp_mx[3][3] = +{ + { { TRUE,TRUE }, { TRUE,TRUE }, { TRUE,FALSE } }, + { { TRUE,TRUE }, { FALSE,FALSE }, { FALSE,FALSE } }, + { { FALSE,TRUE }, { FALSE,FALSE }, { FALSE,FALSE } } +}; + +CONST INT HSCROLL_WIDTH = ::GetSystemMetrics(SM_CYHSCROLL); +CONST INT VSCROLL_WIDTH = ::GetSystemMetrics(SM_CXVSCROLL); + /* FUNCTIONS ********************************************************/ void UpdateScrollbox() { - RECT clientRectScrollbox; - RECT clientRectImageArea; + CONST INT EXTRASIZE = 5; /* 3 px of selection markers + 2 px of border */ + + CRect tempRect; + CSize sizeImageArea; + CSize sizeScrollBox; + INT vmode, hmode; SCROLLINFO si; - scrollboxWindow.GetClientRect(&clientRectScrollbox); - imageArea.GetClientRect(&clientRectImageArea); + + scrollboxWindow.GetWindowRect(&tempRect); + sizeScrollBox = CSize(tempRect.Width(), tempRect.Height()); + + imageArea.GetClientRect(&tempRect); + sizeImageArea = CSize(tempRect.Width(), tempRect.Height()); + sizeImageArea += CSize(EXTRASIZE * 2, EXTRASIZE * 2); + + /* show/hide the scrollbars */ + vmode = (sizeScrollBox.cy < sizeImageArea.cy ? 0 : + (sizeScrollBox.cy < sizeImageArea.cy + HSCROLL_WIDTH ? 1 : 2)); + hmode = (sizeScrollBox.cx < sizeImageArea.cx ? 0 : + (sizeScrollBox.cx < sizeImageArea.cx + VSCROLL_WIDTH ? 1 : 2)); + scrollboxWindow.ShowScrollBar(SB_VERT, sp_mx[vmode][hmode].bVert); + scrollboxWindow.ShowScrollBar(SB_HORZ, sp_mx[vmode][hmode].bHoriz); + si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_PAGE | SIF_RANGE; - si.nMax = clientRectImageArea.right + 6 - 1; si.nMin = 0; - si.nPage = clientRectScrollbox.right; + + si.nMax = sizeImageArea.cx + + (sp_mx[vmode][hmode].bVert == TRUE ? HSCROLL_WIDTH : 0); + si.nPage = sizeScrollBox.cx; scrollboxWindow.SetScrollInfo(SB_HORZ, &si); - scrollboxWindow.GetClientRect(&clientRectScrollbox); - si.nMax = clientRectImageArea.bottom + 6 - 1; - si.nPage = clientRectScrollbox.bottom; + + si.nMax = sizeImageArea.cy + + (sp_mx[vmode][hmode].bHoriz == TRUE ? VSCROLL_WIDTH : 0); + si.nPage = sizeScrollBox.cy; scrollboxWindow.SetScrollInfo(SB_VERT, &si); - scrlClientWindow.MoveWindow( - -scrollboxWindow.GetScrollPos(SB_HORZ), -scrollboxWindow.GetScrollPos(SB_VERT), - max(clientRectImageArea.right + 6, clientRectScrollbox.right), - max(clientRectImageArea.bottom + 6, clientRectScrollbox.bottom), TRUE); + + scrlClientWindow.MoveWindow(-scrollboxWindow.GetScrollPos(SB_HORZ), + -scrollboxWindow.GetScrollPos(SB_VERT), + sizeImageArea.cx, sizeImageArea.cy, TRUE); } LRESULT CScrollboxWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)