Page 1 of 1
wxTreeCtrl с колонками
Posted: Fri Sep 25, 2009 8:05 am
by borr_1
Нужно получить дерево с колонками типа
Col1 Col2 Col3
root
Item1 Item1-Col2 Item1-Col2
Item2 Item2-Col2 Item2-Col2
Видел люди писали, что в 2.9 появиться такая возможность, но я ее там что-то не нашел. Может опять какая-нибудь недокументированная функция?
Смотрел в сторону wxTreeListCtrl, но опят таки непонятно как он будит на совместимость с 2.9, кто нибудь пробовал как его подправить для работы с 2.9?
Posted: Fri Sep 25, 2009 8:33 am
by tan
Posted: Sun Sep 27, 2009 6:36 am
by borr_1
У меня wxTreeListCtrl не компилируется
Я просто добавил wxtreelistctrl.cpp и h в мой проект
И на строчке
Code: Select all
IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl);
BEGIN_EVENT_TABLE(wxTreeListCtrl, wxControl)
EVT_SIZE(wxTreeListCtrl::OnSize)
END_EVENT_TABLE();
Вываливаются ошибки
treelistctrl.cpp|4110|warning: 'static wxObject* wxTreeListCtrl::wxCreateObject()' defined locally after being referenced with dllimport linkage|
treelistctrl.cpp|4112|error: definition of static data member 'wxTreeListCtrl::sm_eventTableEntries' of dllimport'd class|
wxWidgets собраны с UNICODE=1 SHARED=1 MONOLITHIC=1
Эту проблему решил - убрал WXDLLEXPORT из обявления классов в хедере
Posted: Mon Sep 28, 2009 10:17 am
by van_user
Да, DataViewCtrl позволяет получить такое отображение. У меня работает.
Posted: Tue Sep 29, 2009 7:32 am
by borr_1
И верно вроде что-то есть, но для этого на 2.9 переползти надо.
К стати еще такой вопрос в wxTreeCtrl как-нибудь изящно можно переместить ветку (wxTreeItemId). А то у меня получилось только скопировать в новое место, а в старом удалить.
Posted: Tue Sep 29, 2009 12:15 pm
by van_user
borr_1 wrote:И верно вроде что-то есть, но для этого на 2.9 переползти надо.
За исключением сборки самих виджетов у меня мороки с переходом небыло ( возможно прийдется исходники в юникоде сохранить).
borr_1 wrote:К стати еще такой вопрос в wxTreeCtrl как-нибудь изящно можно переместить ветку (wxTreeItemId). А то у меня получилось только скопировать в новое место, а в старом удалить.
. Не встречал другого способа ( хотя сильно и не искал). Найдешь - сообщи
.
Posted: Tue Sep 29, 2009 12:33 pm
by borr_1
возможно прийдется исходники в юникоде сохранить
Они у меня и так да-а-авно уже в юникоде, спасибо T-Rex'у
Вот мой жутко изящный да еще и позаимствованный код по переносу item'a. Я его пока допиливаю. Прошу посмотреть на предмет рацианализации
Code: Select all
bool CopyItemProp(wxTreeItemId old_item, wxTreeItemId new_item)
{
if(!old_item.IsOk() || !new_item.IsOk())
return false;
for(int i=0; i<tree->GetColumnCount(); i++){
tree->SetItemText(new_item, i, tree->GetItemText(old_item, i));
}
/*wxTreeItemId newchilditem = tree->AppendItem(newparent, tree->GetItemText(item));
for(int i=0; i<tree->GetColumnCount(); i++){
tree->SetItemText(newchilditem, i, tree->GetItemText(item, i));
}
//tree->Delete(item);*/
return true;
}
int getItemPos(wxTreeListCtrl* tree, const wxTreeItemId &item){
wxTreeItemId parent = tree->GetItemParent(item);
wxTreeItemIdValue cookie;
wxTreeItemId search_item = tree->GetFirstChild(parent, cookie);
int length = tree->GetChildrenCount(parent);
for(int pos=0; pos<length ; pos++){
if(search_item == item)
return pos;
search_item = tree->GetNextChild(parent, cookie);
}
return -1;
}
//Gets the children at the pos position
wxTreeItemId getChildAt(wxTreeListCtrl* tree, wxTreeItemId parent, int pos){
if(pos < 0 || pos >= tree->GetChildrenCount(parent))
return NULL;
wxTreeItemIdValue cookie;
wxTreeItemId current = tree->GetFirstChild(parent, cookie);
for(int i = 1; i<=pos; i++)
current = tree->GetNextChild(parent, cookie);
return current;
}
//Copy all children of an item to another item
int copyChildren(wxTreeListCtrl* tree, wxTreeItemId old_parent, wxTreeItemId new_parent){
if(old_parent == new_parent)
return -1;
wxTreeItemIdValue cookie;
wxTreeItemId current_new;
wxTreeItemId current_old = tree->GetFirstChild(old_parent, cookie);
int length = tree->GetChildrenCount(old_parent);
for(int pos=0; pos<length ; pos++){
if(current_old.IsOk()){
current_new = tree->AppendItem(new_parent, wxEmptyString /*tree->GetItemText(current_old)*/);
CopyItemProp(current_old, current_new);
copyChildren(tree, current_old, current_new);
}
current_old = tree->GetNextChild(old_parent, cookie);
}
return -1;
}
//Move an item
wxTreeItemId moveItem(wxTreeListCtrl* tree, int old_pos, int new_pos, wxTreeItemId old_parent, wxTreeItemId new_parent){
if(!new_parent.IsOk())
new_parent = old_parent;
if(!old_parent.IsOk() || new_pos <0 || new_pos > tree->GetChildrenCount(new_parent) || old_pos < 0 || old_pos >= tree->GetChildrenCount(old_parent))
return NULL;
wxTreeItemId old_item = getChildAt(tree, old_parent, old_pos);
if(old_pos == new_pos && old_parent == new_parent)
return old_item;
//Duplicating the item
/*wxTreeItemId new_item = (new_pos == tree->GetChildrenCount(new_parent))
? tree->AppendItem(new_parent, tree->GetItemText(old_item))
: tree->InsertItem(new_parent, new_pos, tree->GetItemText(old_item));*/
wxTreeItemId new_item = tree->AppendItem(new_parent, wxEmptyString/*tree->GetItemText(old_item)*/);
CopyItemProp(old_item, new_item);
//Copy all children
copyChildren(tree, old_item, new_item);
//Remove old item
if(tree->IsExpanded(old_item))
tree->Expand(new_item);
tree->Delete(old_item);
return new_item;
}
Прежде чем сделать moveItem нужно проверить не тащит ли юзер родителя в его же дочерние итему (здесь и основная проблема)
Code: Select all
wxTreeItemIdValue cookie;
wxTreeItemId current_old = tree->GetFirstChild(item, cookie);
if(current_old == newitem)
return wxDragNone;
for(int i =0; i<tree->GetChildrenCount(item); i++){
wxTreeItemId current_old = tree->GetNextChild(item, cookie);
if(current_old == newitem)
return wxDragNone;
}
Posted: Thu Oct 01, 2009 6:28 am
by van_user
borr_1 wrote:Вот мой жутко изящный да еще и позаимствованный код по переносу item'a. Я его пока допиливаю. Прошу посмотреть на предмет рацианализации
Ничего глупого не увидел
. Вроде бы все четко и логично.
borr_1 wrote:Прежде чем сделать moveItem нужно проверить не тащит ли юзер родителя в его же дочерние итему (здесь и основная проблема)
Code: Select all
wxTreeItemIdValue cookie;
wxTreeItemId current_old = tree->GetFirstChild(item, cookie);
if(current_old == newitem)
return wxDragNone;
for(int i =0; i<tree->GetChildrenCount(item); i++){
wxTreeItemId current_old = tree->GetNextChild(item, cookie);
if(current_old == newitem)
return wxDragNone;
}
Может лучше будет не проверять не вниз, а вверх? ( не перебирать дочерние, а у нового смотреть кто родитель. Зависит от того что реализуешь - либо широкие, либо глубокие
деревья). Кроме перебора другого способа не вижу.