diff options
author | George Hazan <george.hazan@gmail.com> | 2023-10-14 17:42:13 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-10-14 17:42:13 +0300 |
commit | eb8648aa4e5ffed389904993be910b63b595fd6e (patch) | |
tree | ad677d542ff061ce6bc3f9aa19b4f9101267d48b /plugins/NewStory/src | |
parent | 7d6fac7a960515f1cdf9f1ce7945bdc72ab16301 (diff) |
fixes #3651 (NewStory: упоротая прокрутка)
Diffstat (limited to 'plugins/NewStory/src')
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 103 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.h | 4 |
2 files changed, 70 insertions, 37 deletions
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index 1e3cf1cd89..bfc51147f2 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -699,51 +699,63 @@ void NewstoryListData::ToggleSelection(int iFirst, int iLast) void NewstoryListData::LineUp() { - if (AtTop()) - return; - - if (scrollTopPixel == 0) - scrollTopItem--; - else { - cachedMaxTopItem = -1; - scrollTopPixel = 0; - } - FixScrollPosition(); - InvalidateRect(m_hwnd, 0, FALSE); + if (!AtTop()) + ScrollUp(10); } void NewstoryListData::LineDown() { - if (AtBottom()) - return; - - scrollTopItem++; - FixScrollPosition(); - InvalidateRect(m_hwnd, 0, FALSE); + if (!AtBottom()) + ScrollDown(10); } void NewstoryListData::PageUp() { - if (AtTop()) + if (!AtTop()) + ScrollUp(cachedWindowHeight); +} + +void NewstoryListData::PageDown() +{ + if (!AtBottom()) + ScrollDown(cachedWindowHeight); +} + +void NewstoryListData::ScrollBottom() +{ + if (!totalCount) return; - if (scrollTopPixel == 0) - scrollTopItem -= 10; - else { - scrollTopItem -= 9; - scrollTopPixel = 0; - } - FixScrollPosition(); + scrollTopItem = cachedMaxTopItem; + scrollTopPixel = cachedMaxTopPixel; + FixScrollPosition(true); InvalidateRect(m_hwnd, 0, FALSE); } -void NewstoryListData::PageDown() +void NewstoryListData::ScrollDown(int deltaY) { - if (AtBottom()) - return; + int iHeight = GetItemHeight(scrollTopItem) + scrollTopPixel; + if (iHeight > deltaY) + scrollTopPixel -= deltaY; + else { + deltaY -= iHeight; + + bool bFound = false; + for (int i = scrollTopItem + 1; i < totalCount; i++) { + iHeight = GetItemHeight(i); + if (iHeight > deltaY) { + scrollTopPixel = deltaY - iHeight; + scrollTopItem = i; + bFound = true; + break; + } + deltaY -= iHeight; + } + if (!bFound) + scrollTopItem = scrollTopPixel = 0; + FixScrollPosition(); + } - scrollTopItem = cachedMaxDrawnItem - 1; - FixScrollPosition(); InvalidateRect(m_hwnd, 0, FALSE); } @@ -754,14 +766,33 @@ void NewstoryListData::ScrollTop() InvalidateRect(m_hwnd, 0, FALSE); } -void NewstoryListData::ScrollBottom() +void NewstoryListData::ScrollUp(int deltaY) { - if (!totalCount) - return; + int reserveY = -scrollTopPixel; // distance in pixels between the top event beginning and the window top coordinate - scrollTopItem = cachedMaxTopItem; - scrollTopPixel = cachedMaxTopPixel; - FixScrollPosition(true); + if (reserveY >= deltaY) + scrollTopPixel += deltaY; // stay on the same event, just move up + else { + deltaY -= reserveY; // move to the appropriate event first, then calculate the gap + + bool bFound = false; + for (int i = scrollTopItem - 1; i >= 0; i--) { + int iHeight = GetItemHeight(i); + if (iHeight > deltaY) { + scrollTopPixel = deltaY - iHeight; + scrollTopItem = i; + bFound = true; + break; + } + deltaY -= iHeight; + } + + if (!bFound) + scrollTopItem = scrollTopPixel = 0; + + FixScrollPosition(); + } + InvalidateRect(m_hwnd, 0, FALSE); } diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index c2b722a90e..332c8eb7d7 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -83,8 +83,10 @@ struct NewstoryListData : public MZeroedObject void Quote(); void RecalcScrollBar(); void ScheduleDraw(); - void ScrollTop(); void ScrollBottom(); + void ScrollDown(int deltaY); + void ScrollTop(); + void ScrollUp(int deltaY); void SetCaret(int idx, bool bEnsureVisible = true); void SetContact(MCONTACT hContact); void SetDialog(CSrmmBaseDialog *pDialog); |