Make wxTreeCtrl::EnsureVisible() work while frozen in wxMSW

Scrolling the item into view to make it visible didn't work since the
changes of badf6bc300, 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.
This commit is contained in:
Vadim Zeitlin 2019-07-09 23:00:11 +02:00
parent 1cdba2b5ab
commit e8712b3c56
4 changed files with 35 additions and 0 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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