Release v0.6.9: notify about updates and fix Settings scroll flicker
This commit is contained in:
+43
-11
@@ -71,17 +71,48 @@ void arrangeWindow(HWND w)
|
||||
RECT client{}; GetClientRect(w, &client);
|
||||
int extraWidth = layout->history ? std::max(0, int(client.right) - scale(w, layout->width)) : 0;
|
||||
int extraHeight = layout->history ? std::max(0, int(client.bottom) - scale(w, layout->height)) : 0;
|
||||
struct Move { HWND child; RECT rect; };
|
||||
std::vector<Move> moves;
|
||||
for (const auto &[child, r] : layout->controls)
|
||||
{
|
||||
int id = GetDlgCtrlID(child);
|
||||
SetWindowPos(child, nullptr, scale(w, r.left) - layout->x,
|
||||
scale(w, r.top) - layout->y + (id >= 110 && id <= 114 ? extraHeight : 0),
|
||||
scale(w, r.right - r.left) + (id == 101 || id == 102 ? extraWidth : 0),
|
||||
scale(w, r.bottom - r.top) + (id == 102 ? extraHeight : 0),
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
RECT next{scale(w, r.left) - layout->x,
|
||||
scale(w, r.top) - layout->y + (id >= 110 && id <= 114 ? extraHeight : 0)};
|
||||
next.right = next.left + scale(w, r.right - r.left) + (id == 101 || id == 102 ? extraWidth : 0);
|
||||
next.bottom = next.top + scale(w, r.bottom - r.top) + (id == 102 ? extraHeight : 0);
|
||||
RECT current{}; GetWindowRect(child, ¤t);
|
||||
MapWindowPoints(nullptr, w, reinterpret_cast<POINT *>(¤t), 2);
|
||||
if (!EqualRect(¤t, &next)) moves.push_back({child, next});
|
||||
}
|
||||
if (!moves.empty())
|
||||
{
|
||||
auto batch = BeginDeferWindowPos((int)moves.size());
|
||||
for (const auto &move : moves)
|
||||
{
|
||||
if (!batch) break;
|
||||
auto r = move.rect;
|
||||
batch = DeferWindowPos(batch, move.child, nullptr, r.left, r.top, r.right-r.left, r.bottom-r.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
if (!batch || !EndDeferWindowPos(batch))
|
||||
for (const auto &move : moves)
|
||||
{
|
||||
auto r = move.rect;
|
||||
SetWindowPos(move.child, nullptr, r.left, r.top, r.right-r.left, r.bottom-r.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
layout->arranging = false;
|
||||
InvalidateRect(w, nullptr, TRUE);
|
||||
}
|
||||
void scrollWindow(HWND w, WindowLayout *layout, bool horizontal, int requested)
|
||||
{
|
||||
SCROLLINFO info{sizeof(info), SIF_RANGE | SIF_PAGE};
|
||||
GetScrollInfo(w, horizontal ? SB_HORZ : SB_VERT, &info);
|
||||
int next = std::clamp(requested, info.nMin, std::max(info.nMin, info.nMax - std::max(0, (int)info.nPage - 1)));
|
||||
int &position = horizontal ? layout->x : layout->y;
|
||||
if (position == next) return;
|
||||
position = next;
|
||||
arrangeWindow(w);
|
||||
}
|
||||
void revealControl(HWND child)
|
||||
{
|
||||
@@ -127,7 +158,7 @@ LRESULT CALLBACK layoutProc(HWND w, UINT msg, WPARAM wp, LPARAM lp, UINT_PTR, DW
|
||||
bool vertical = msg == WM_VSCROLL;
|
||||
SCROLLINFO info{sizeof(info), SIF_ALL};
|
||||
GetScrollInfo(w, vertical ? SB_VERT : SB_HORZ, &info);
|
||||
int &position = vertical ? layout->y : layout->x;
|
||||
int position = vertical ? layout->y : layout->x;
|
||||
switch (LOWORD(wp))
|
||||
{
|
||||
case SB_LINEUP: position -= scale(w, 32); break;
|
||||
@@ -138,7 +169,7 @@ LRESULT CALLBACK layoutProc(HWND w, UINT msg, WPARAM wp, LPARAM lp, UINT_PTR, DW
|
||||
case SB_BOTTOM: position = info.nMax; break;
|
||||
case SB_THUMBTRACK: case SB_THUMBPOSITION: position = info.nTrackPos; break;
|
||||
}
|
||||
arrangeWindow(w);
|
||||
scrollWindow(w, layout, !vertical, position);
|
||||
return 0;
|
||||
}
|
||||
if (layout->scrolling && (msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL))
|
||||
@@ -148,8 +179,9 @@ LRESULT CALLBACK layoutProc(HWND w, UINT msg, WPARAM wp, LPARAM lp, UINT_PTR, DW
|
||||
remainder += GET_WHEEL_DELTA_WPARAM(wp);
|
||||
int steps = remainder / WHEEL_DELTA;
|
||||
remainder %= WHEEL_DELTA;
|
||||
(horizontal ? layout->x : layout->y) += steps * scale(w, 48) * (msg == WM_MOUSEHWHEEL ? 1 : -1);
|
||||
arrangeWindow(w);
|
||||
if (steps)
|
||||
scrollWindow(w, layout, horizontal, (horizontal ? layout->x : layout->y) +
|
||||
steps * scale(w, 48) * (msg == WM_MOUSEHWHEEL ? 1 : -1));
|
||||
return 0;
|
||||
}
|
||||
if (msg == WM_NCDESTROY)
|
||||
@@ -276,7 +308,7 @@ HWND makeWindow(App &app, const wchar_t *cls, const wchar_t *title, WNDPROC proc
|
||||
RegisterClassW(&wc);
|
||||
UINT dpi = GetDpiForSystem();
|
||||
RECT rect{0, 0, MulDiv(width, dpi, 96), MulDiv(height, dpi, 96)};
|
||||
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | extra;
|
||||
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN | extra;
|
||||
if (resizable) style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||
AdjustWindowRectExForDpi(&rect, style, FALSE, WS_EX_APPWINDOW, dpi);
|
||||
POINT cursor{};
|
||||
|
||||
Reference in New Issue
Block a user