diff options
author | George Hazan <george.hazan@gmail.com> | 2023-12-09 13:43:21 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-12-09 13:43:21 +0300 |
commit | 2845fe740489165d8996ac11976a1821394020ac (patch) | |
tree | 53680318c2139ce2d7e16b95063f0aea172f0656 | |
parent | 9e03c9fc0bb94d4ae048c827862238cd644679d6 (diff) |
fixes #3969 (Newstory: если доскроллить вверх до первого сообщения, то подгрузить еще сообщений)
-rw-r--r-- | plugins/NewStory/src/history_array.cpp | 29 | ||||
-rw-r--r-- | plugins/NewStory/src/history_array.h | 1 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 69 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.h | 4 |
4 files changed, 90 insertions, 13 deletions
diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp index 8065adfb20..22feefbb07 100644 --- a/plugins/NewStory/src/history_array.cpp +++ b/plugins/NewStory/src/history_array.cpp @@ -120,6 +120,35 @@ ItemData* ItemData::checkPrev(ItemData *pPrev) ///////////////////////////////////////////////////////////////////////////////////////// +ItemData* ItemData::checkNext(ItemData *pPrev) +{ + m_grouping = GROUPING_NONE; + if (!pPrev || !g_plugin.bMsgGrouping) + return this; + + // we don't group anything but messages + if (!fetch()) + return this; + + if (dbe.eventType != EVENTTYPE_MESSAGE) + return this; + + pPrev->fetch(); + if (isEqual(this, pPrev)) { + if (pPrev->m_grouping == GROUPING_NONE) { + pPrev->m_grouping = GROUPING_HEAD; + if (pPrev->m_bLoaded) + pPrev->setText(); + } + m_grouping = GROUPING_ITEM; + if (m_bLoaded) + setText(); + } + return this; +} + +///////////////////////////////////////////////////////////////////////////////////////// + static bool isEqualGC(const ItemData *p1, const ItemData *p2) { if (p1->dbe.eventType != p2->dbe.eventType) diff --git a/plugins/NewStory/src/history_array.h b/plugins/NewStory/src/history_array.h index 7e8d01b23d..81ca3df4af 100644 --- a/plugins/NewStory/src/history_array.h +++ b/plugins/NewStory/src/history_array.h @@ -31,6 +31,7 @@ struct ItemData ItemData(); ~ItemData(); + ItemData* checkNext(ItemData *pPrev); ItemData* checkPrev(ItemData *pPrev); ItemData* checkPrevGC(ItemData *pPrev); void checkCreate(HWND hwnd); diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index 8de1503e1b..1471992670 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -245,6 +245,15 @@ void NewstoryListData::BeginEditItem() ///////////////////////////////////////////////////////////////////////////////////////// +void NewstoryListData::CalcBottom() +{ + int maxTopItem = totalCount, tmp = 0; + while (maxTopItem > 0 && tmp < cachedWindowHeight) + tmp += GetItemHeight(--maxTopItem); + cachedMaxTopItem = maxTopItem; + cachedMaxTopPixel = (cachedWindowHeight < tmp) ? cachedWindowHeight - tmp : 0; +} + void NewstoryListData::Clear() { items.clear(); @@ -415,13 +424,8 @@ void NewstoryListData::FixScrollPosition(bool bForce) { EndEditItem(false); - if (bForce || cachedMaxTopItem != scrollTopItem) { - int maxTopItem = totalCount, tmp = 0; - while (maxTopItem > 0 && tmp < cachedWindowHeight) - tmp += GetItemHeight(--maxTopItem); - cachedMaxTopItem = maxTopItem; - cachedMaxTopPixel = (cachedWindowHeight < tmp) ? cachedWindowHeight - tmp : 0; - } + if (bForce || cachedMaxTopItem != scrollTopItem) + CalcBottom(); if (scrollTopItem < 0) scrollTopItem = 0; @@ -620,8 +624,9 @@ void NewstoryListData::RecalcScrollBar() si.nPage = (totalCount <= 10) ? totalCount - 1 : 10; si.nPos = scrollTopItem; - if (si.nPos != cachedScrollbarPos) { + if (si.nPos != cachedScrollbarPos || si.nMax != cachedScrollbarMax) { cachedScrollbarPos = si.nPos; + cachedScrollbarMax = si.nMax; SetScrollInfo(m_hwnd, SB_VERT, &si, TRUE); } } @@ -731,12 +736,48 @@ void NewstoryListData::ToggleSelection(int iFirst, int iLast) InvalidateRect(m_hwnd, 0, FALSE); } +void NewstoryListData::TryUp(int iCount) +{ + if (totalCount == 0) + return; + + auto *pTop = GetItem(0); + MCONTACT hContact = pTop->hContact; + if (pTop->hEvent == 0 || hContact == 0) + return; + + int i; + for (i = 0; i < iCount; i++) { + MEVENT hPrev = db_event_prev(hContact, pTop->hEvent); + if (hPrev == 0) + break; + + auto *p = items.insert(0); + p->hContact = hContact; + p->hEvent = hPrev; + totalCount++; + } + + ItemData *pPrev = nullptr; + for (int j = 0; j < i + 1; j++) { + auto *pItem = GetItem(j); + pPrev = pItem->checkNext(pPrev); + } + + caret = 0; + CalcBottom(); + FixScrollPosition(); + InvalidateRect(m_hwnd, 0, FALSE); +} + ///////////////////////////////////////////////////////////////////////////////////////// // Navigation by coordinates void NewstoryListData::LineUp() { - if (!AtTop()) + if (AtTop()) + TryUp(1); + else ScrollUp(10); } @@ -748,7 +789,9 @@ void NewstoryListData::LineDown() void NewstoryListData::PageUp() { - if (!AtTop()) + if (AtTop()) + TryUp(10); + else ScrollUp(cachedWindowHeight); } @@ -763,7 +806,9 @@ void NewstoryListData::PageDown() void NewstoryListData::EventUp() { - if (caret > 0) + if (caret == 0) + TryUp(1); + else SetPos(caret - 1); } @@ -778,7 +823,7 @@ void NewstoryListData::EventPageUp() if (caret >= 10) SetPos(caret - 10); else - SetPos(0); + TryUp(caret == 10 ? 1 : 10 - caret); } void NewstoryListData::EventPageDown() diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index a6c87e6622..4dddd88e21 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -17,7 +17,7 @@ struct NewstoryListData : public MZeroedObject int cachedMaxTopPixel; int cachedWindowWidth = -1, cachedWindowHeight = -1; int cachedMaxDrawnItem = -1; - int cachedScrollbarPos = -1; + int cachedScrollbarPos = -1, cachedScrollbarMax = -1; int totalCount; RECT rcLastPaint; @@ -41,6 +41,7 @@ struct NewstoryListData : public MZeroedObject bool AtBottom(void) const; bool AtTop(void) const; void BeginEditItem(); + void CalcBottom(); void Clear(); void ClearSelection(int iFirst, int iLast); void Copy(bool bTextOnly = false); @@ -83,6 +84,7 @@ struct NewstoryListData : public MZeroedObject void SetSelection(int iFirst, int iLast); void ToggleBookmark(); void ToggleSelection(int iFirst, int iLast); + void TryUp(int iCount); }; void InitNewstoryControl(); |