Drag and Drop at wxTreeCtrl
September 26th, 2009 Begemot Posted in Использование
Добавлял тут drag and drop к дереву, для своего легкого менеджера заметок, порядком намучался. А все оказывается не так и сложно, надо просто делать так как доктор прописал.
Задача была такая – есть дерево, хочу что бы перетаскивать можно было:
- Ветви внутри дерева
- Данные (текст) из дерева наружу
- Текст снаружи в дерево.
Где-то в вверху
Разумеется приходится писать своего наследника wxDropTarget, а вот порождать что-то свое от wxDataObject в итоге не пришлось, хотя сначала я и там нагородил целый класс:) Обошелся просто wxCustomDataObject. Итак упрощенный код, упрощенный потому что для решения реальной задачи приходится писать еще кучу кода, которая сейчас только затруднит понимание реализации перетаскивания.
Итак наш класс для DropTarget:
{
public:
FlashnoteTreeDropTarget(CMyFNTreeCtrl * _tree) : wxDropTarget(new wxDataObjectComposite), tree(_tree)
{
((wxDataObjectComposite*)GetDataObject())->Add(new wxCustomDataObject(FlashnoteTreeItemFormatId));
((wxDataObjectComposite*)GetDataObject())->Add(new wxTextDataObject);
}
// override base class (pure) virtuals
virtual wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def) { return OnDragOver(x, y, def); }
virtual void OnLeave() { }
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
{
if (!GetData())
{
wxLogError(wxT("Failed to get drag and drop data"));
return wxDragNone;
}
wxDataObjectComposite * data = (wxDataObjectComposite*) GetDataObject();
const wxDataFormat format = data->GetReceivedFormat();
const int size = data->GetDataSize(format);
if (format == wxDataFormat(FlashnoteTreeItemFormatId))
{
wxTreeItemId item;
data->GetDataHere(format, &item);
wxASSERT(item.IsOk());
wxLogDebug(wxT("Received our format : id - %i, string id - %s, date item - %i"), format.GetFormatId(), format.GetId().c_str(), item);
}
else if (format.GetFormatId() == wxDF_UNICODETEXT)
{
wxString text;
data->GetDataHere(format, text.GetWriteBuf(size));
text.UngetWriteBuf(size);
wxLogDebug(wxT("Received Text : format id - %i, data size = %i, text - %s"), format.GetFormatId(), size, text.c_str());
}
else wxFAIL_MSG(wxString::Format(_T("What format - %i"), format.GetFormatId()));
// wxTreeItemId item = tree->HitTest(wxPoint(x, y));
return def;
}
private:
CMyFNTreeCtrl * tree;
};
Разумеется не забываем сделать SetDropTarget(new FlashnoteTreeDropTarget(this)); в процессе создание дерева. Дальше код обработчик начала перетаскивания EVT_TREE_BEGIN_DRAG(wxID_ANY, CMyFNTreeCtrl::OnBeginDrag)
wxCustomDataObject * myIDData = new wxCustomDataObject(FlashnoteTreeItemFormatId);
wxTreeItemId item = event.GetItem();
wxLogDebug(_T("send item - %i"), item);
myIDData->SetData(sizeof(wxTreeItemId), &item);
myData.Add(myIDData);
wxTextDataObject * myTextData = new wxTextDataObject(wxT("Этот текст будет перемещен."));
myData.Add(myTextData);
wxDropSource dragSource(this);
dragSource.SetData(myData);
//wxDragResult result =
dragSource.DoDragDrop(wxDrag_AllowMove);
За 100% компилируемость и рабочесть кода не ручаюсь, надергал из проекта, не проверял – может что забыл. Но идея должна быть понятна.
September 29th, 2009 at 2:13 pm
Ух.. а чего у тебя такого произошло с синтакс хайлайтером?
September 30th, 2009 at 1:29 pm
А он лайаут портит.