summaryrefslogtreecommitdiff
path: root/plugins/NewStory
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-08-14 15:46:34 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-08-14 15:46:34 +0300
commit0fc80f4ce48b9d28653703257f94e5f4f402dbb0 (patch)
tree99aa00208618b37f02d1cf08a3a13d0513e9b215 /plugins/NewStory
parent3859e4cd13fd6de47e609dcac72a03d41b4b9dc0 (diff)
fixes #3628 (NewStory: автопрокрутка журнала при открытии новой вкладки в фоне)
Diffstat (limited to 'plugins/NewStory')
-rw-r--r--plugins/NewStory/src/history_control.cpp97
-rw-r--r--plugins/NewStory/src/history_control.h12
-rw-r--r--plugins/NewStory/src/history_dlg.cpp6
-rw-r--r--plugins/NewStory/src/history_log.cpp15
4 files changed, 80 insertions, 50 deletions
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp
index e86c882451..badcc70562 100644
--- a/plugins/NewStory/src/history_control.cpp
+++ b/plugins/NewStory/src/history_control.cpp
@@ -60,13 +60,24 @@ void NewstoryListData::OnContextMenu(int index, POINT pt)
Menu_DestroyNestedMenu(hMenu);
}
-void NewstoryListData::OnResize(int newWidth)
+void NewstoryListData::OnResize(int newWidth, int newHeight)
{
- if (newWidth == cachedWindowWidth)
- return;
+ bool bDraw = false;
+ if (newWidth != cachedWindowWidth) {
+ cachedWindowWidth = newWidth;
+ for (int i = 0; i < totalCount; i++)
+ LoadItem(i)->savedHeight = -1;
+ bDraw = true;
+ }
+
+ if (newHeight != cachedWindowHeight) {
+ cachedWindowHeight = newHeight;
+ FixScrollPosition(true);
+ bDraw = true;
+ }
- for (int i = 0; i < totalCount; i++)
- LoadItem(i)->savedHeight = -1;
+ if (bDraw)
+ InvalidateRect(hwnd, 0, FALSE);
}
void NewstoryListData::OnTimer(CTimer *pTimer)
@@ -115,6 +126,28 @@ void NewstoryListData::AddSelection(int iFirst, int iLast)
InvalidateRect(hwnd, 0, FALSE);
}
+bool NewstoryListData::AtBottom(void) const
+{
+ if (cachedMaxDrawnItem > totalCount)
+ return true;
+
+ if (cachedMaxDrawnItem == totalCount && cachedMaxTopPixel >= scrollTopPixel)
+ return true;
+
+ return false;
+}
+
+bool NewstoryListData::AtTop(void) const
+{
+ if (scrollTopItem < 0)
+ return true;
+
+ if (scrollTopItem == 0 && scrollTopPixel == 0)
+ return true;
+
+ return false;
+}
+
void NewstoryListData::BeginEditItem(int index, bool bReadOnly)
{
if (hwndEditBox)
@@ -238,7 +271,7 @@ void NewstoryListData::EndEditItem(bool bAccept)
}
DestroyWindow(hwndEditBox);
- hwndEditBox = 0;
+ hwndEditBox = nullptr;
}
void NewstoryListData::EnsureVisible(int item)
@@ -279,17 +312,12 @@ void NewstoryListData::FixScrollPosition(bool bForce)
{
EndEditItem(false);
- RECT rc;
- GetWindowRect(hwnd, &rc);
- int windowHeight = rc.bottom - rc.top;
-
- if (bForce || windowHeight != cachedWindowHeight || cachedMaxTopItem != scrollTopItem) {
+ if (bForce || cachedMaxTopItem != scrollTopItem) {
int maxTopItem = totalCount, tmp = 0;
- while (maxTopItem > 0 && tmp < windowHeight)
+ while (maxTopItem > 0 && tmp < cachedWindowHeight)
tmp += GetItemHeight(--maxTopItem);
cachedMaxTopItem = maxTopItem;
- cachedWindowHeight = windowHeight;
- cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0;
+ cachedMaxTopPixel = (cachedWindowHeight < tmp) ? cachedWindowHeight - tmp : 0;
}
if (scrollTopItem < 0)
@@ -459,6 +487,16 @@ void NewstoryListData::SetCaret(int idx, bool bEnsureVisible)
EnsureVisible(idx);
}
}
+void NewstoryListData::SetContact(MCONTACT hContact)
+{
+ WindowList_Add(g_hNewstoryLogs, hwnd, hContact);
+}
+
+void NewstoryListData::SetDialog(CSrmmBaseDialog *pDlg)
+{
+ if (pMsgDlg = pDlg)
+ SetContact(pDlg->m_hContact);
+}
void NewstoryListData::SetPos(int pos)
{
@@ -519,7 +557,7 @@ void NewstoryListData::ToggleSelection(int iFirst, int iLast)
void NewstoryListData::LineUp()
{
- if (scrollTopItem <= 0)
+ if (AtTop())
return;
if (scrollTopPixel == 0)
@@ -534,7 +572,7 @@ void NewstoryListData::LineUp()
void NewstoryListData::LineDown()
{
- if (cachedMaxDrawnItem >= totalCount && cachedMaxTopPixel >= 0)
+ if (AtBottom())
return;
scrollTopItem++;
@@ -544,7 +582,7 @@ void NewstoryListData::LineDown()
void NewstoryListData::PageUp()
{
- if (scrollTopItem <= 0)
+ if (AtTop())
return;
if (scrollTopPixel == 0)
@@ -559,7 +597,7 @@ void NewstoryListData::PageUp()
void NewstoryListData::PageDown()
{
- if (cachedMaxDrawnItem >= totalCount && cachedMaxTopPixel >= 0)
+ if (AtBottom())
return;
scrollTopItem = cachedMaxDrawnItem - 1;
@@ -569,7 +607,8 @@ void NewstoryListData::PageDown()
void NewstoryListData::ScrollTop()
{
- EnsureVisible(0);
+ scrollTopItem = scrollTopPixel = 0;
+ FixScrollPosition(true);
InvalidateRect(hwnd, 0, FALSE);
}
@@ -578,7 +617,9 @@ void NewstoryListData::ScrollBottom()
if (!totalCount)
return;
- EnsureVisible(totalCount - 1);
+ scrollTopItem = cachedMaxTopItem;
+ scrollTopPixel = cachedMaxTopPixel;
+ FixScrollPosition(true);
InvalidateRect(hwnd, 0, FALSE);
}
@@ -704,19 +745,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
}
return TRUE;
- case NSM_SEEKEND:
- data->SetCaret(data->totalCount - 1);
- break;
-
- case NSM_SET_SRMM:
- data->pMsgDlg = (CSrmmBaseDialog *)lParam;
- lParam = data->pMsgDlg->m_hContact;
- __fallthrough;
-
- case NSM_SET_CONTACT:
- WindowList_Add(g_hNewstoryLogs, hwnd, lParam);
- break;
-
case NSM_COPY:
{
CMStringW res;
@@ -774,8 +802,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
break;
case WM_SIZE:
- data->OnResize(LOWORD(lParam));
- InvalidateRect(hwnd, 0, FALSE);
+ data->OnResize(LOWORD(lParam), HIWORD(lParam));
break;
case WM_COMMAND:
diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h
index 2f63056a97..f557d9c694 100644
--- a/plugins/NewStory/src/history_control.h
+++ b/plugins/NewStory/src/history_control.h
@@ -33,12 +33,9 @@ enum
NSM_GETARRAY,
//
- NSM_SEEKEND,
NSM_SEEKTIME,
//
- NSM_SET_SRMM, // act inside SRMM dialog
- NSM_SET_CONTACT, // set hContact
NSM_SET_OPTIONS, // options were changed
NSM_LAST
@@ -54,10 +51,9 @@ struct NewstoryListData : public MZeroedObject
int scrollTopPixel; // y coord of topmost item, this should be negative or zero
int caret;
int selStart = -1;
- int cachedWindowHeight;
int cachedMaxTopItem; // the largest ID of top item to avoid empty space
int cachedMaxTopPixel;
- int cachedWindowWidth = -1;
+ int cachedWindowWidth = -1, cachedWindowHeight = -1;
int cachedMaxDrawnItem = -1;
int cachedScrollbarPos = -1;
unsigned int cachedScrollbarPage = -1;
@@ -74,13 +70,15 @@ struct NewstoryListData : public MZeroedObject
CSrmmBaseDialog *pMsgDlg = nullptr;
void OnContextMenu(int index, POINT pt);
- void OnResize(int newWidth);
+ void OnResize(int newWidth, int newHeight);
void OnTimer(CTimer *pTimer);
void AddChatEvent(SESSION_INFO *si, const LOGINFO *lin);
void AddEvent(MCONTACT hContact, MEVENT hFirstEvent, int iCount);
void AddResults(const OBJLIST<SearchResult> &results);
void AddSelection(int iFirst, int iLast);
+ bool AtBottom(void) const;
+ bool AtTop(void) const;
void BeginEditItem(int index, bool bReadOnly);
void Clear();
void ClearSelection(int iFirst, int iLast);
@@ -102,6 +100,8 @@ struct NewstoryListData : public MZeroedObject
void ScrollTop();
void ScrollBottom();
void SetCaret(int idx, bool bEnsureVisible = true);
+ void SetContact(MCONTACT hContact);
+ void SetDialog(CSrmmBaseDialog *pDialog);
void SetPos(int pos);
void SetSelection(int iFirst, int iLast);
void ToggleBookmark();
diff --git a/plugins/NewStory/src/history_dlg.cpp b/plugins/NewStory/src/history_dlg.cpp
index 66655f5f7e..9bb1f2e790 100644
--- a/plugins/NewStory/src/history_dlg.cpp
+++ b/plugins/NewStory/src/history_dlg.cpp
@@ -434,7 +434,7 @@ public:
ShowHideControls();
UpdateTitle();
- m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_histWindow.GetHwnd(), GWLP_USERDATA);
+ m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_histWindow.GetHwnd(), 0);
if (m_hContact != INVALID_CONTACT_ID) {
Utils_RestoreWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
@@ -453,8 +453,8 @@ public:
m_dwOptions |= WND_OPT_SEARCHBAR;
}
- m_histWindow.SendMsg(NSM_SET_CONTACT, m_hContact, 0);
- m_histWindow.SendMsg(NSM_SEEKEND, 0, 0);
+ m_histCtrl->SetContact(m_hContact);
+ m_histCtrl->ScrollBottom();
Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_NEWSTORY));
diff --git a/plugins/NewStory/src/history_log.cpp b/plugins/NewStory/src/history_log.cpp
index 8f16ca1e92..573c47ac57 100644
--- a/plugins/NewStory/src/history_log.cpp
+++ b/plugins/NewStory/src/history_log.cpp
@@ -19,8 +19,8 @@ public:
m_hwnd = ::CreateWindowW(_T(NEWSTORYLIST_CLASS), L"NewStory", WS_VISIBLE | WS_CHILD | WS_TABSTOP,
0, 0, rc.left - rc.right, rc.bottom - rc.top, m_pDlg.GetHwnd(), 0, m_pDlg.GetInst(), 0);
- SendMessage(m_hwnd, NSM_SET_SRMM, 0, (LPARAM)&m_pDlg);
- m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_hwnd, GWLP_USERDATA);
+ m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_hwnd, 0);
+ m_histCtrl->SetDialog(&m_pDlg);
}
void Detach() override
@@ -32,9 +32,7 @@ public:
bool AtBottom() override
{
- int totalCount = SendMessage(m_hwnd, NSM_GETCOUNT, 0, 0);
- int caret = SendMessage(m_hwnd, NSM_GETCARET, 0, 0);
- return caret >= totalCount - 1;
+ return m_histCtrl->AtBottom();
}
void Clear() override
@@ -72,6 +70,8 @@ public:
void Resize() override
{
+ bool bottomScroll = m_pDlg.isChat() ? AtBottom() : true;
+
RECT rc;
GetWindowRect(GetDlgItem(m_pDlg.GetHwnd(), IDC_SRMM_LOG), &rc);
@@ -79,11 +79,14 @@ public:
ScreenToClient(GetParent(m_hwnd), &pt);
::SetWindowPos(m_hwnd, 0, pt.x, pt.y, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOZORDER);
+
+ if (bottomScroll)
+ ScrollToBottom();
}
void ScrollToBottom() override
{
- ::SendMessage(m_hwnd, NSM_SEEKEND, 0, 0);
+ m_histCtrl->ScrollBottom();
}
};