summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-10-14 17:42:13 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-10-14 17:42:13 +0300
commiteb8648aa4e5ffed389904993be910b63b595fd6e (patch)
treead677d542ff061ce6bc3f9aa19b4f9101267d48b /plugins/NewStory/src
parent7d6fac7a960515f1cdf9f1ce7945bdc72ab16301 (diff)
fixes #3651 (NewStory: упоротая прокрутка)
Diffstat (limited to 'plugins/NewStory/src')
-rw-r--r--plugins/NewStory/src/history_control.cpp103
-rw-r--r--plugins/NewStory/src/history_control.h4
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);