diff options
author | George Hazan <george.hazan@gmail.com> | 2023-08-14 15:46:34 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-08-14 15:46:34 +0300 |
commit | 0fc80f4ce48b9d28653703257f94e5f4f402dbb0 (patch) | |
tree | 99aa00208618b37f02d1cf08a3a13d0513e9b215 /plugins/NewStory | |
parent | 3859e4cd13fd6de47e609dcac72a03d41b4b9dc0 (diff) |
fixes #3628 (NewStory: автопрокрутка журнала при открытии новой вкладки в фоне)
Diffstat (limited to 'plugins/NewStory')
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 97 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.h | 12 | ||||
-rw-r--r-- | plugins/NewStory/src/history_dlg.cpp | 6 | ||||
-rw-r--r-- | plugins/NewStory/src/history_log.cpp | 15 |
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(); } }; |