diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 36bb41f431..628f84ce8e 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -61,6 +61,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(TreeTest_DeleteChildren, MyFrame::OnDeleteChildren) EVT_MENU(TreeTest_DeleteAll, MyFrame::OnDeleteAll) EVT_MENU(TreeTest_Recreate, MyFrame::OnRecreate) + EVT_MENU(TreeTest_EnsureVisible, MyFrame::OnEnsureVisible) END_EVENT_TABLE() BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl) @@ -129,6 +130,8 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) tree_menu->AppendSeparator(); tree_menu->Append(TreeTest_Bold, "Make item &bold"); tree_menu->Append(TreeTest_UnBold, "Make item ¬ bold"); + tree_menu->AppendSeparator(); + tree_menu->Append(TreeTest_EnsureVisible, "Make the last item &visible"); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, "&File"); @@ -262,6 +265,11 @@ void MyFrame::OnRecreate(wxCommandEvent& event) m_treeCtrl->AddTestItemsToTree(3, 2); } +void MyFrame::OnEnsureVisible(wxCommandEvent& event) +{ + m_treeCtrl->DoEnsureVisible(); +} + // MyTreeCtrl implementation IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl) @@ -316,24 +324,31 @@ void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent, size_t depth, size_t folder) { - if ( depth > 0 ) - { - wxString str; - for ( size_t n = 0; n < numChildren; n++ ) + if ( depth > 0 ) { - // at depth 1 elements won't have any more children - if (depth == 1) - str.Printf("%s child %d.%d", "File", folder, n + 1); - else - str.Printf("%s child %d","Folder", n + 1); + wxString str; + for ( size_t n = 0; n < numChildren; n++ ) + { + // at depth 1 elements won't have any more children + if (depth == 1) + str.Printf("%s child %d.%d", "File", folder, n + 1); + else + str.Printf("%s child %d", "Folder", n + 1); - int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; - wxTreeItemId id = AppendItem(idParent, str, image, image, - new MyTreeItemData(str)); - AddItemsRecursively(id, numChildren, depth - 1, n + 1); + int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; + wxTreeItemId id = AppendItem(idParent, str, image, image, + new MyTreeItemData(str)); + + // remember the last child for OnEnsureVisible() + if ( depth == 1 && n == numChildren - 1 ) + { + m_lastItem = id; + } + + AddItemsRecursively(id, numChildren, depth - 1, n + 1); + } } - } - //else: done! + //else: done! } void MyTreeCtrl::AddTestItemsToTree(size_t numChildren, diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index e0299c0045..e51e97389b 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -65,6 +65,7 @@ public: void DoSortChildren(const wxTreeItemId& item, bool reverse = FALSE) { m_reverseSort = reverse; wxTreeCtrl::SortChildren(item); } + void DoEnsureVisible() { EnsureVisible(m_lastItem); } protected: virtual int OnCompareItems(const wxTreeItemId& item1, @@ -78,6 +79,7 @@ private: wxImageList *m_imageListNormal; bool m_reverseSort; // flag for OnCompareItems + wxTreeItemId m_lastItem; // for OnEnsureVisible() // NB: due to an ugly wxMSW hack you _must_ use DECLARE_DYNAMIC_CLASS() // if you want your overloaded OnCompareItems() to be called. @@ -107,6 +109,8 @@ public: void OnSetBold(wxCommandEvent& WXUNUSED(event)) { DoSetBold(TRUE); } void OnClearBold(wxCommandEvent& WXUNUSED(event)) { DoSetBold(FALSE); } + void OnEnsureVisible(wxCommandEvent& event); + void OnRename(wxCommandEvent& event); void OnSort(wxCommandEvent& event) { DoSort(); } void OnSortRev(wxCommandEvent& event) { DoSort(TRUE); } @@ -136,5 +140,6 @@ enum TreeTest_DeleteChildren, TreeTest_DeleteAll, TreeTest_Recreate, + TreeTest_EnsureVisible, TreeTest_Ctrl = 100 -}; \ No newline at end of file +}; diff --git a/src/generic/treectrl.cpp b/src/generic/treectrl.cpp index d9cb6dbb24..0bb4b72c4f 100644 --- a/src/generic/treectrl.cpp +++ b/src/generic/treectrl.cpp @@ -908,6 +908,16 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) { wxGenericTreeItem *gitem = item.m_pItem; + // first expand all parent branches + wxGenericTreeItem *parent = gitem->GetParent(); + while ( parent && !parent->IsExpanded() ) + { + Expand(parent); + + parent = parent->GetParent(); + } + + // now scroll to the item int item_y = gitem->GetY(); int start_x = 0; @@ -926,11 +936,9 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) m_anchor->GetSize( x, y ); y += 2*m_lineHeight; int x_pos = GetScrollPos( wxHORIZONTAL ); - SetScrollbars( 10, 10, x/10, y/10, x_pos, (item_y-client_h/2)/10 ); - return; + SetScrollbars( 10, 10, x/10, y/10, x_pos, (item_y-client_h/2)/10 ); } - - if (item_y > start_y+client_h-16) + else if (item_y > start_y+client_h-16) { int x = 0; int y = 0; @@ -938,7 +946,6 @@ void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) y += 2*m_lineHeight; int x_pos = GetScrollPos( wxHORIZONTAL ); SetScrollbars( 10, 10, x/10, y/10, x_pos, (item_y-client_h/2)/10 ); - return; } } @@ -1049,7 +1056,7 @@ void wxTreeCtrl::AdjustMyScrollbars() void wxTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { - /* render bold items in bold */ + // render bold items in bold wxFont fontOld; wxFont fontNew; @@ -1058,7 +1065,7 @@ void wxTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) fontOld = dc.GetFont(); if (fontOld.Ok()) { - /* @@ is there any better way to make a bold variant of old font? */ + // VZ: is there any better way to make a bold variant of old font? fontNew = wxFont( fontOld.GetPointSize(), fontOld.GetFamily(), fontOld.GetStyle(), @@ -1111,7 +1118,7 @@ void wxTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) dc.SetBackgroundMode(wxTRANSPARENT); dc.DrawText( item->GetText(), image_w + item->GetX(), item->GetY() ); - /* restore normal font for bold items */ + // restore normal font for bold items if (fontOld.Ok()) { dc.SetFont( fontOld); @@ -1198,10 +1205,11 @@ void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int & PaintLevel( children[n], dc, level+1, y ); } - /* it may happen that the item is expanded but has no items (when you - * delete all its children for example) - don't draw the vertical line - * in this case */ - if (count > 0) dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY ); + // it may happen that the item is expanded but has no items (when you + // delete all its children for example) - don't draw the vertical line + // in this case + if (count > 0) + dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY ); } } @@ -1455,7 +1463,8 @@ void wxTreeCtrl::OnMouse( wxMouseEvent &event ) return; } - if (!IsSelected(item)) SelectItem(item); /* we dont support multiple selections, BTW */ + if (!IsSelected(item)) + SelectItem(item); /* we dont support multiple selections, BTW */ if (event.LeftDClick()) { @@ -1477,7 +1486,8 @@ void wxTreeCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) ) /* after all changes have been done to the tree control, * we actually redraw the tree when everything is over */ - if (!m_dirty) return; + if (!m_dirty) + return; m_dirty = FALSE; @@ -1498,7 +1508,7 @@ void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, i if ( !item->IsExpanded() ) { - /* we dont need to calculate collapsed branches */ + // we dont need to calculate collapsed branches return; } @@ -1507,7 +1517,7 @@ void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, i for ( size_t n = 0; n < count; n++ ) { y += m_lineHeight; - CalculateLevel( children[n], dc, level+1, y ); /* recurse */ + CalculateLevel( children[n], dc, level+1, y ); // recurse } } @@ -1524,7 +1534,7 @@ void wxTreeCtrl::CalculatePositions() m_lineHeight = (int)(dc.GetCharHeight() + 4); int y = m_lineHeight / 2 + 2; - CalculateLevel( m_anchor, dc, 0, y ); /* start recursion */ + CalculateLevel( m_anchor, dc, 0, y ); // start recursion } void wxTreeCtrl::RefreshSubtree(wxGenericTreeItem *item)