Редактирование: WxWidgets FAQ Drag & Drop
Материал из Wiki.crossplatform.ru
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
+ | Wikipedia: | ||
+ | In computer graphical user interfaces, drag-and-drop is the action of (or support for the action of) clicking on a virtual object and dragging it to a different location or onto another virtual object. In general, it can be used to invoke many kinds of actions, or create various types of associations between two abstract objects. | ||
+ | Drag and drop functionality is one of the most visible aspects of the graphical user interface. | ||
+ | Drag and drop operation enables you to do complex things intuitively. | ||
+ | |||
+ | In drag and drop we basically drag some data from a data source to a data target. | ||
+ | So we must have: | ||
+ | * Data object | ||
+ | * Data source | ||
+ | * Data target | ||
+ | |||
+ | For drag & drop of text, wxWidgets has a predefined <b>wxTextDropTarget</b> class. | ||
+ | |||
+ | In the following example, we drag and drop file names from the upper list control to the bottom one. | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | #include <wx/wx.h> | ||
+ | #include <wx/dnd.h> | ||
+ | |||
+ | class TextDrop : public wxFrame | ||
+ | { | ||
+ | public: | ||
+ | TextDrop(const wxString& title); | ||
+ | |||
+ | void OnSelect(wxCommandEvent& event); | ||
+ | void OnDragInit(wxListEvent& event); | ||
+ | |||
+ | wxGenericDirCtrl *m_gdir; | ||
+ | wxListCtrl *m_lc1; | ||
+ | wxListCtrl *m_lc2; | ||
+ | |||
+ | }; | ||
+ | |||
+ | |||
+ | class MyTextDropTarget : public wxTextDropTarget | ||
+ | { | ||
+ | public: | ||
+ | MyTextDropTarget(wxListCtrl *owner); | ||
+ | |||
+ | virtual bool OnDropText(wxCoord x, wxCoord y, | ||
+ | const wxString& data); | ||
+ | |||
+ | wxListCtrl *m_owner; | ||
+ | |||
+ | }; | ||
+ | |||
+ | |||
+ | </source> | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | #include "textdrop.h" | ||
+ | #include <wx/treectrl.h> | ||
+ | #include <wx/dirctrl.h> | ||
+ | #include <wx/dir.h> | ||
+ | #include <wx/splitter.h> | ||
+ | |||
+ | |||
+ | TextDrop::TextDrop(const wxString& title) | ||
+ | : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200)) | ||
+ | { | ||
+ | |||
+ | wxSplitterWindow *spl1 = new wxSplitterWindow(this, -1); | ||
+ | wxSplitterWindow *spl2 = new wxSplitterWindow(spl1, -1); | ||
+ | m_gdir = new wxGenericDirCtrl(spl1, -1, wxT("/home/"), | ||
+ | wxPoint(-1, -1), wxSize(-1, -1), wxDIRCTRL_DIR_ONLY); | ||
+ | |||
+ | m_lc1 = new wxListCtrl(spl2, -1, wxPoint(-1, -1), | ||
+ | wxSize(-1, -1), wxLC_LIST); | ||
+ | m_lc2 = new wxListCtrl(spl2, -1, wxPoint(-1, -1), | ||
+ | wxSize(-1, -1), wxLC_LIST); | ||
+ | |||
+ | MyTextDropTarget *mdt = new MyTextDropTarget(m_lc2); | ||
+ | m_lc2->SetDropTarget(mdt); | ||
+ | |||
+ | Connect(m_lc1->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, | ||
+ | wxListEventHandler(TextDrop::OnDragInit)); | ||
+ | |||
+ | wxTreeCtrl *tree = m_gdir->GetTreeCtrl(); | ||
+ | |||
+ | spl2->SplitHorizontally(m_lc1, m_lc2); | ||
+ | spl1->SplitVertically(m_gdir, spl2); | ||
+ | |||
+ | Connect(tree->GetId(), wxEVT_COMMAND_TREE_SEL_CHANGED, | ||
+ | wxCommandEventHandler(TextDrop::OnSelect)); | ||
+ | |||
+ | Center(); | ||
+ | } | ||
+ | |||
+ | MyTextDropTarget::MyTextDropTarget(wxListCtrl *owner) | ||
+ | { | ||
+ | m_owner = owner; | ||
+ | } | ||
+ | |||
+ | bool MyTextDropTarget::OnDropText(wxCoord x, wxCoord y, | ||
+ | const wxString& data) | ||
+ | { | ||
+ | |||
+ | m_owner->InsertItem(0, data); | ||
+ | return true; | ||
+ | |||
+ | } | ||
+ | |||
+ | void TextDrop::OnSelect(wxCommandEvent& event) | ||
+ | { | ||
+ | wxString filename; | ||
+ | wxString path = m_gdir->GetPath(); | ||
+ | wxDir dir(path); | ||
+ | |||
+ | bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES); | ||
+ | |||
+ | int i = 0; | ||
+ | |||
+ | m_lc1->ClearAll(); | ||
+ | m_lc2->ClearAll(); | ||
+ | |||
+ | while ( cont ) | ||
+ | { | ||
+ | m_lc1->InsertItem(i, filename); | ||
+ | cont = dir.GetNext(&filename); | ||
+ | i++; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | void TextDrop::OnDragInit(wxListEvent& event) | ||
+ | { | ||
+ | |||
+ | wxString text = m_lc1->GetItemText(event.GetIndex()); | ||
+ | |||
+ | wxTextDataObject tdo(text); | ||
+ | wxDropSource tds(tdo, m_lc1); | ||
+ | tds.DoDragDrop(wxDrag_CopyOnly); | ||
+ | |||
+ | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | #include <wx/wx.h> | ||
+ | |||
+ | class MyApp : public wxApp | ||
+ | { | ||
+ | public: | ||
+ | virtual bool OnInit(); | ||
+ | }; | ||
+ | |||
+ | </source> | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | #include "main.h" | ||
+ | #include "textdrop.h" | ||
+ | |||
+ | IMPLEMENT_APP(MyApp) | ||
+ | |||
+ | bool MyApp::OnInit() | ||
+ | { | ||
+ | |||
+ | TextDrop *td = new TextDrop(wxT("TextDrop")); | ||
+ | td->Show(true); | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | In our example, we have a window separated into three parts. This is done by the <i>wxSplitterWindow</i> widget. | ||
+ | In the left part of the window, we have a generic directory control. We display all directories available under our filesystem. In the right part there are two windows. The first displays all files under a selected directory. | ||
+ | The second one is used for dragging the files. | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | MyTextDropTarget *mdt = new MyTextDropTarget(m_lc2); | ||
+ | m_lc2->SetDropTarget(mdt); | ||
+ | </source> | ||
+ | |||
+ | Here we define a text drop target. | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | wxString text = m_lc1->GetItemText(event.GetIndex()); | ||
+ | |||
+ | wxTextDataObject tdo(text); | ||
+ | wxDropSource tds(tdo, m_lc1); | ||
+ | tds.DoDragDrop(wxDrag_CopyOnly); | ||
+ | </source> | ||
+ | |||
+ | In the <i>OnDragInit()</i> method, we define a text data object and a drop source object. We call the <i>DoDragDrop()</i> method. The <i>wxDrag_CopyOnly</i> constant allows only copying of data. | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | bool MyTextDropTarget::OnDropText(wxCoord x, wxCoord y, | ||
+ | const wxString& data) | ||
+ | { | ||
+ | m_owner->InsertItem(0, data); | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | During the dropping operation, we insert the text data into the list control. | ||
+ | |||
+ | [[image: wxwidgets_faq_textdrop.jpg | center]] | ||
+ | |||
+ | [[Категория:WxWidgets]] |