From e8712b3c5664740dcc57cb0840cc7da7f06136d0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jul 2019 23:00:11 +0200 Subject: [PATCH] Make wxTreeCtrl::EnsureVisible() work while frozen in wxMSW Scrolling the item into view to make it visible didn't work since the changes of badf6bc300b0874e737b657ebdadef75024bff62, which suppressed scrolling completely while frozen, any longer. Work around it by remembering the item to make visible and actually doing it when the control is thawed. Also add menu item to call Freeze()/Thaw() on wxTreeCtrl in the sample to make testing this and similar problems easier. Closes #18435. --- include/wx/msw/treectrl.h | 3 +++ samples/treectrl/treetest.cpp | 12 ++++++++++++ samples/treectrl/treetest.h | 2 ++ src/msw/treectrl.cpp | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index e2c1740b11..eeca2d15b3 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -315,6 +315,9 @@ private: // Virtual root item, if wxTR_HIDE_ROOT is set. void* m_pVirtualRoot; + // Item to call EnsureVisible() on when the tree is thawed, if necessary. + wxTreeItemId m_htEnsureVisibleOnThaw; + // the starting item for selection with Shift wxTreeItemId m_htSelStart, m_htClickedItem; wxPoint m_ptClick; diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index b4840a6fa0..827cbdd99c 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -111,6 +111,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) MENU_LINK(DeleteChildren) MENU_LINK(DeleteAll) MENU_LINK(Recreate) + MENU_LINK(FreezeThaw) MENU_LINK(ToggleImages) MENU_LINK(ToggleStates) MENU_LINK(ToggleBell) @@ -261,6 +262,7 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) style_menu->AppendSeparator(); style_menu->Append(TreeTest_ResetStyle, "&Reset to default\tF10"); + tree_menu->AppendCheckItem(TreeTest_FreezeThaw, "&Freeze the tree"); tree_menu->Append(TreeTest_Recreate, "&Recreate the tree"); tree_menu->Append(TreeTest_CollapseAndReset, "C&ollapse and reset"); tree_menu->AppendSeparator(); @@ -664,6 +666,16 @@ void MyFrame::OnDeleteAll(wxCommandEvent& WXUNUSED(event)) m_treeCtrl->DeleteAllItems(); } +void MyFrame::OnFreezeThaw(wxCommandEvent& event) +{ + if ( event.IsChecked() ) + m_treeCtrl->Freeze(); + else + m_treeCtrl->Thaw(); + + wxLogMessage("The tree is %sfrozen", m_treeCtrl->IsFrozen() ? "" : "not "); +} + void MyFrame::OnRecreate(wxCommandEvent& event) { OnDeleteAll(event); diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index 99182002d0..43439ea8d5 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -215,6 +215,7 @@ public: void OnDeleteChildren(wxCommandEvent& event); void OnDeleteAll(wxCommandEvent& event); + void OnFreezeThaw(wxCommandEvent& event); void OnRecreate(wxCommandEvent& event); void OnToggleButtons(wxCommandEvent& event); void OnToggleImages(wxCommandEvent& event); @@ -335,6 +336,7 @@ enum TreeTest_Delete, TreeTest_DeleteChildren, TreeTest_DeleteAll, + TreeTest_FreezeThaw, TreeTest_Recreate, TreeTest_ToggleImages, TreeTest_ToggleStates, diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 8e1025ab24..41ac550aa4 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -1724,6 +1724,7 @@ void wxTreeCtrl::DeleteAllItems() TreeItemUnlocker unlock_all; // invalidate all the items we store as they're going to become invalid + m_htEnsureVisibleOnThaw = m_htSelStart = m_htClickedItem = wxTreeItemId(); @@ -1996,6 +1997,16 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) { wxCHECK_RET( !IsHiddenRoot(item), wxT("can't show hidden root item") ); + if ( IsFrozen() ) + { + // We can't ensure that the item is visible if it involves scrolling + // while we're frozen, as we disable scrolling in this case. So just + // remember that item we were supposed to make visible and actually do + // it when the control is thawed. + m_htEnsureVisibleOnThaw = item; + return; + } + // no error return (void)TreeView_EnsureVisible(GetHwnd(), HITEM(item)); } @@ -3953,6 +3964,13 @@ void wxTreeCtrl::DoThaw() wxMSWWinStyleUpdater(GetHwnd()).TurnOff(TVS_NOSCROLL); wxTreeCtrlBase::DoThaw(); + + if ( !IsFrozen() && m_htEnsureVisibleOnThaw.IsOk() ) + { + // Really do the job of EnsureVisible() now that we can. + EnsureVisible(m_htEnsureVisibleOnThaw); + m_htEnsureVisibleOnThaw.Unset(); + } } #endif // wxUSE_TREECTRL