treectlg.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,169 行 · 第 1/5 页
CPP
2,169 行
{
wxTreeItemId id = GetRootItem();
if (!id.IsOk())
return id;
do
{
if (IsVisible(id))
return id;
id = GetNext(id);
} while (id.IsOk());
return wxTreeItemId();
}
wxTreeItemId wxGenericTreeCtrl::GetNextVisible(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
wxTreeItemId id = item;
if (id.IsOk())
{
while (id = GetNext(id), id.IsOk())
{
if (IsVisible(id))
return id;
}
}
return wxTreeItemId();
}
wxTreeItemId wxGenericTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const
{
wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") );
wxFAIL_MSG(wxT("not implemented"));
return wxTreeItemId();
}
// called by wxTextTreeCtrl when it marks itself for deletion
void wxGenericTreeCtrl::ResetTextControl()
{
m_textCtrl = NULL;
}
// find the first item starting with the given prefix after the given item
wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent,
const wxString& prefixOrig) const
{
// match is case insensitive as this is more convenient to the user: having
// to press Shift-letter to go to the item starting with a capital letter
// would be too bothersome
wxString prefix = prefixOrig.Lower();
// determine the starting point: we shouldn't take the current item (this
// allows to switch between two items starting with the same letter just by
// pressing it) but we shouldn't jump to the next one if the user is
// continuing to type as otherwise he might easily skip the item he wanted
wxTreeItemId id = idParent;
if ( prefix.length() == 1 )
{
id = GetNext(id);
}
// look for the item starting with the given prefix after it
while ( id.IsOk() && !GetItemText(id).Lower().StartsWith(prefix) )
{
id = GetNext(id);
}
// if we haven't found anything...
if ( !id.IsOk() )
{
// ... wrap to the beginning
id = GetRootItem();
if ( HasFlag(wxTR_HIDE_ROOT) )
{
// can't select virtual root
id = GetNext(id);
}
// and try all the items (stop when we get to the one we started from)
while ( id != idParent && !GetItemText(id).Lower().StartsWith(prefix) )
{
id = GetNext(id);
}
}
return id;
}
// -----------------------------------------------------------------------------
// operations
// -----------------------------------------------------------------------------
wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId,
size_t previous,
const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem;
if ( !parent )
{
// should we give a warning here?
return AddRoot(text, image, selImage, data);
}
m_dirty = true; // do this first so stuff below doesn't cause flicker
wxGenericTreeItem *item =
new wxGenericTreeItem( parent, text, image, selImage, data );
if ( data != NULL )
{
data->m_pItem = item;
}
parent->Insert( item, previous );
return item;
}
wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
wxCHECK_MSG( !m_anchor, wxTreeItemId(), wxT("tree can have only one root") );
m_dirty = true; // do this first so stuff below doesn't cause flicker
m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text,
image, selImage, data);
if ( data != NULL )
{
data->m_pItem = m_anchor;
}
if (HasFlag(wxTR_HIDE_ROOT))
{
// if root is hidden, make sure we can navigate
// into children
m_anchor->SetHasPlus();
m_anchor->Expand();
CalculatePositions();
}
if (!HasFlag(wxTR_MULTIPLE))
{
m_current = m_key_current = m_anchor;
m_current->SetHilight( true );
}
return m_anchor;
}
wxTreeItemId wxGenericTreeCtrl::PrependItem(const wxTreeItemId& parent,
const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
return DoInsertItem(parent, 0u, text, image, selImage, data);
}
wxTreeItemId wxGenericTreeCtrl::InsertItem(const wxTreeItemId& parentId,
const wxTreeItemId& idPrevious,
const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem;
if ( !parent )
{
// should we give a warning here?
return AddRoot(text, image, selImage, data);
}
int index = -1;
if (idPrevious.IsOk())
{
index = parent->GetChildren().Index((wxGenericTreeItem*) idPrevious.m_pItem);
wxASSERT_MSG( index != wxNOT_FOUND,
wxT("previous item in wxGenericTreeCtrl::InsertItem() is not a sibling") );
}
return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data);
}
wxTreeItemId wxGenericTreeCtrl::InsertItem(const wxTreeItemId& parentId,
size_t before,
const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem;
if ( !parent )
{
// should we give a warning here?
return AddRoot(text, image, selImage, data);
}
return DoInsertItem(parentId, before, text, image, selImage, data);
}
wxTreeItemId wxGenericTreeCtrl::AppendItem(const wxTreeItemId& parentId,
const wxString& text,
int image, int selImage,
wxTreeItemData *data)
{
wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem;
if ( !parent )
{
// should we give a warning here?
return AddRoot(text, image, selImage, data);
}
return DoInsertItem( parent, parent->GetChildren().Count(), text,
image, selImage, data);
}
void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item)
{
wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, GetId() );
event.m_item = item;
event.SetEventObject( this );
ProcessEvent( event );
}
// Don't leave edit or selection on a child which is about to disappear
void wxGenericTreeCtrl::ChildrenClosing(wxGenericTreeItem* item)
{
if (m_textCtrl != NULL && item != m_textCtrl->item() && IsDescendantOf(item, m_textCtrl->item())) {
m_textCtrl->StopEditing();
}
if (item != m_key_current && IsDescendantOf(item, m_key_current)) {
m_key_current = NULL;
}
if (IsDescendantOf(item, m_select_me)) {
m_select_me = item;
}
if (item != m_current && IsDescendantOf(item, m_current)) {
m_current->SetHilight( false );
m_current = NULL;
m_select_me = item;
}
}
void wxGenericTreeCtrl::DeleteChildren(const wxTreeItemId& itemId)
{
m_dirty = true; // do this first so stuff below doesn't cause flicker
wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
ChildrenClosing(item);
item->DeleteChildren(this);
}
void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId)
{
m_dirty = true; // do this first so stuff below doesn't cause flicker
wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
if (m_textCtrl != NULL && IsDescendantOf(item, m_textCtrl->item()))
{
// can't delete the item being edited, cancel editing it first
m_textCtrl->StopEditing();
}
wxGenericTreeItem *parent = item->GetParent();
// don't keep stale pointers around!
if ( IsDescendantOf(item, m_key_current) )
{
// Don't silently change the selection:
// do it properly in idle time, so event
// handlers get called.
// m_key_current = parent;
m_key_current = NULL;
}
// m_select_me records whether we need to select
// a different item, in idle time.
if ( m_select_me && IsDescendantOf(item, m_select_me) )
{
m_select_me = parent;
}
if ( IsDescendantOf(item, m_current) )
{
// Don't silently change the selection:
// do it properly in idle time, so event
// handlers get called.
// m_current = parent;
m_current = NULL;
m_select_me = parent;
}
// remove the item from the tree
if ( parent )
{
parent->GetChildren().Remove( item ); // remove by value
}
else // deleting the root
{
// nothing will be left in the tree
m_anchor = NULL;
}
// and delete all of its children and the item itself now
item->DeleteChildren(this);
SendDeleteEvent(item);
if (item == m_select_me)
m_select_me = NULL;
delete item;
}
void wxGenericTreeCtrl::DeleteAllItems()
{
if ( m_anchor )
{
Delete(m_anchor);
}
}
void wxGenericTreeCtrl::Expand(const wxTreeItemId& itemId)
{
wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
wxCHECK_RET( item, _T("invalid item in wxGenericTreeCtrl::Expand") );
wxCHECK_RET( !HasFlag(wxTR_HIDE_ROOT) || itemId != GetRootItem(),
_T("can't expand hidden root") );
if ( !item->HasPlus() )
return;
if ( item->IsExpanded() )
return;
wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, GetId() );
event.m_item = item;
event.SetEventObject( this );
if ( ProcessEvent( event ) && !event.IsAllowed() )
{
// cancelled by program
return;
}
item->Expand();
CalculatePositions();
RefreshSubtree(item);
event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED);
ProcessEvent( event );
}
void wxGenericTreeCtrl::ExpandAll(const wxTreeItemId& item)
{
if ( !HasFlag(wxTR_HIDE_ROOT) || item != GetRootItem())
{
Expand(item);
if ( !IsExpanded(item) )
return;
}
wxTreeItemIdValue cookie;
wxTreeItemId child = GetFirstChild(item, cookie);
while ( child.IsOk() )
{
ExpandAll(child);
child = GetNextChild(item, cookie);
}
}
void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId)
{
wxCHECK_RET( !HasFlag(wxTR_HIDE_ROOT) || itemId != GetRootItem(),
_T("can't collapse hidden root") );
wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
if ( !item->IsExpanded() )
return;
wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, GetId() );
event.m_item = item;
event.SetEventObject( this );
if ( ProcessEvent( event ) && !event.IsAllowed() )
{
// cancelled by program
return;
}
ChildrenClosing(item);
item->Collapse();
#if 0 // TODO why should items be collapsed recursively?
wxArrayGenericTreeItems& children = item->GetChildren();
size_t count = children.Count();
for ( size_t n = 0; n < count; n++ )
{
Collapse(children[n]);
}
#endif
CalculatePositions();
RefreshSubtree(item);
event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
ProcessEvent( event );
}
void wxGenericTreeCtrl::CollapseAndReset(const wxTreeItemId& item)
{
Collapse(item);
DeleteChildren(item);
}
void wxGenericTreeCtrl::Toggle(const wxTreeItemId& itemId)
{
wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem;
if (item->IsExpanded())
Collapse(itemId);
else
Expand(itemId);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?