summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-12-09 13:43:21 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-12-09 13:43:21 +0300
commit2845fe740489165d8996ac11976a1821394020ac (patch)
tree53680318c2139ce2d7e16b95063f0aea172f0656
parent9e03c9fc0bb94d4ae048c827862238cd644679d6 (diff)
fixes #3969 (Newstory: если доскроллить вверх до первого сообщения, то подгрузить еще сообщений)
-rw-r--r--plugins/NewStory/src/history_array.cpp29
-rw-r--r--plugins/NewStory/src/history_array.h1
-rw-r--r--plugins/NewStory/src/history_control.cpp69
-rw-r--r--plugins/NewStory/src/history_control.h4
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();