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
По-моему это:
http://docs.wxwidgets.org/trunk/classwx ... _ctrl.html

сам не пробовал

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. Я его пока допиливаю. Прошу посмотреть на предмет рацианализации
Ничего глупого не увидел :wink: . Вроде бы все четко и логично.
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;
}
Может лучше будет не проверять не вниз, а вверх? ( не перебирать дочерние, а у нового смотреть кто родитель. Зависит от того что реализуешь - либо широкие, либо глубокие :) деревья). Кроме перебора другого способа не вижу.