返回介绍

Drag and Drop in wxWidgets

发布于 2025-02-22 22:19:35 字数 5109 浏览 0 评论 0 收藏 0

Wikipedia defines drag & drop as 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 operations enable us to do complex things intuitively.

In drag and drop we basically drag some data from a data source to a data target. We deal with the following objects:

  • Data object
  • Data source
  • Data target

For drag & drop of text, wxWidgets has a predefined wxTextDropTarget class.

In the following example, we drag and drop file names from the upper list control to the bottom one.

textdrop.h

#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;
 
};

textdrop.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);

}

main.h

#include <wx/wx.h>

class MyApp : public wxApp
{
  public:
  virtual bool OnInit();
};

main.cpp

#include "main.h"
#include "textdrop.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{

  TextDrop *td = new TextDrop(wxT("TextDrop"));
  td->Show(true);

  return true;
}

In our example, we have a window separated into three parts. This is done by the wxSplitterWindow 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.

MyTextDropTarget *mdt = new MyTextDropTarget(m_lc2);
m_lc2->SetDropTarget(mdt);

Here we define a text drop target.

wxString text = m_lc1->GetItemText(event.GetIndex());

wxTextDataObject tdo(text);
wxDropSource tds(tdo, m_lc1);
tds.DoDragDrop(wxDrag_CopyOnly);

In the OnDragInit() method, we define a text data object and a drop source object. We call the DoDragDrop() method. The wxDrag_CopyOnly constant allows only copying of data.

bool MyTextDropTarget::OnDropText(wxCoord x, wxCoord y, 
  const wxString& data)
{
  m_owner->InsertItem(0, data);
  return true;
}

During the dropping operation, we insert the text data into the list control.

Drag & Drop
Figure: Drag & Drop

In this chapter, we covered drag and drop operations in wxWidgets.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文