Advertisement
Guest User

wxListBox Drag Reorder

a guest
Jun 5th, 2013
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.83 KB | None | 0 0
  1. #include <wx/wx.h>
  2. #include <wx/listbox.h>
  3.  
  4. class TestBox : public wxListBox
  5. {
  6. private:
  7.     wxColour* m_secondColor;
  8.     bool m_isDragging;
  9.     bool m_isPressing;
  10.     bool m_hasScrolled;
  11.     wxPoint m_lastPos;
  12.     void paintLine(int y);
  13.     void OnLeftDown(wxMouseEvent &event);
  14.     void OnLeftUp(wxMouseEvent &event);
  15.     void OnMove(wxMouseEvent &event);
  16.  
  17. public:
  18.     TestBox(wxWindow* parent, wxWindowID id);
  19.     void appendToList(wxString item, int pos);
  20.  
  21.     DECLARE_EVENT_TABLE()
  22. };
  23.  
  24. BEGIN_EVENT_TABLE(TestBox, wxListBox)
  25.   EVT_LEFT_DOWN         (TestBox::OnLeftDown)
  26.   EVT_LEFT_UP           (TestBox::OnLeftUp)
  27.   EVT_MOTION            (TestBox::OnMove)
  28. END_EVENT_TABLE()
  29.  
  30. TestBox::TestBox(wxWindow* parent, wxWindowID id)
  31.     : wxListBox(parent, id, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxBORDER_SIMPLE | wxLB_OWNERDRAW, wxDefaultValidator, wxListBoxNameStr)
  32. {
  33.     m_secondColor = new wxColour(235, 250, 255);
  34.     m_isDragging = false;
  35.     m_isPressing = false;
  36.     m_hasScrolled = false;
  37.     SetSize(610,430);
  38. }
  39.  
  40. void TestBox::appendToList(wxString item, int pos)
  41. {
  42.     DeselectAll();
  43.  
  44.     int newPos = Insert(item, pos);
  45.     SetSelection(newPos);
  46.  
  47.     int size = GetCount();
  48.     bool foundPlaying = false;
  49.     for (int i = 0; i < size; i++) {
  50.         GetItem(i)->SetBackgroundColour((i % 2 == 0 ? *m_secondColor : *wxWHITE));
  51.     }
  52. }
  53.  
  54. void TestBox::paintLine(int y)
  55. {
  56.     wxClientDC dc(this);
  57.     wxSize size = GetSize();
  58.     int width = size.GetWidth();
  59.  
  60.     dc.SetPen(*wxGREY_PEN);
  61.     dc.SetBrush(*wxGREY_BRUSH);
  62.     dc.DrawLine(0, y, width, y);
  63. }
  64.  
  65. void TestBox::OnLeftDown(wxMouseEvent &event)
  66. {
  67.     m_isPressing = true;
  68.     if(!m_isDragging) {
  69.         m_lastPos = event.GetPosition();
  70.     }
  71.     event.Skip();
  72. }
  73.  
  74. void TestBox::OnLeftUp(wxMouseEvent &event)
  75. {
  76.     m_isPressing = false;
  77.  
  78.     if(m_isDragging) {
  79.         m_isDragging = false;
  80.         int scrollPos = GetScrollPos(wxVERTICAL);
  81.         wxRect rect;
  82.         wxArrayInt listIndex;
  83.         static int itemHeight = -1;
  84.  
  85.          // If the itemHeight isn't set, set it here and now
  86.         if (itemHeight == -1) {
  87.             GetItemRect(0, rect);
  88.             itemHeight = rect.height;
  89.         }
  90.  
  91.         GetSelections(listIndex);
  92.         if(listIndex.size() != 1) {
  93.             m_hasScrolled = false;
  94.             return;
  95.         }
  96.  
  97.         int index = listIndex.Item(0);
  98.  
  99.         GetItemRect(index, rect);
  100.         int currentY = rect.y;
  101.  
  102.         wxString item = GetString(index);
  103.         this->Delete(index);
  104.  
  105.         if(m_hasScrolled) {
  106.             index = scrollPos + ((event.GetY() + itemHeight/2) / itemHeight);
  107.             m_hasScrolled = false;
  108.         } else {
  109.             index = HitTest(event.GetX(), (event.GetY() + itemHeight / 2) -1);
  110.         }
  111.  
  112.         if (index > GetCount()) {
  113.             index = GetCount();
  114.         }
  115.  
  116.         int y = itemHeight * (index - scrollPos);
  117.         if(y > currentY) {
  118.             index--;
  119.         }
  120.  
  121.         appendToList(item, index);
  122.     }
  123.  
  124.     event.Skip();
  125. }
  126.  
  127. void TestBox::OnMove(wxMouseEvent &event)
  128. {
  129.     if(!m_isPressing && !m_isDragging) {
  130.         return;
  131.     }
  132.  
  133.     if (event.m_controlDown || event.m_shiftDown) {
  134.         m_isPressing = false;
  135.         m_isDragging = false;
  136.         Refresh();
  137.         Update();
  138.         return;
  139.     }
  140.  
  141.     if (!m_isDragging) {
  142.         static const int dragMinX = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
  143.         static const int dragMinY = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
  144.         const wxPoint& pos = event.GetPosition();
  145.         const wxPoint ofs = pos - m_lastPos;
  146.  
  147.         if ( abs(ofs.x) > dragMinX || abs(ofs.y) > dragMinY) {
  148.             m_isDragging = true;
  149.         }
  150.     } else {
  151.         static int lastY;
  152.         static long lastTimestamp = 0;
  153.         static int itemHeight = -1;
  154.  
  155.          // If the itemHeight isn't set, set it here and now
  156.         if (itemHeight == -1) {
  157.             wxRect rect;
  158.             GetItemRect(0, rect);
  159.             itemHeight = rect.height;
  160.         }
  161.  
  162.         int y = event.GetY();
  163.         int index = (y + itemHeight / 2) / itemHeight;
  164.  
  165.         if (index > GetCount())
  166.             index = GetCount();
  167.  
  168.         y = itemHeight * index;
  169.  
  170.         // y > 25000 is a strange behaviour, happens when the cursor is outside the widget
  171.         if (y <= 0 || y > 25000) {
  172.             LineUp();
  173.             m_hasScrolled = true;
  174.         } else if (y >= GetSize().GetHeight()) {
  175.             LineDown();
  176.             m_hasScrolled = true;
  177.         }
  178.  
  179.         if(event.GetTimestamp() - 60 > lastTimestamp && y != lastY) {
  180.             Refresh();
  181.             Update();
  182.             paintLine(y);
  183.             lastTimestamp = event.GetTimestamp();
  184.         }
  185.         lastY = y;
  186.         return;
  187.     }
  188.     event.Skip();
  189. }
  190.  
  191. class TestFrame : public wxFrame
  192. {
  193. public:
  194.     TestFrame(const wxString& title)
  195.        : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(640, 480))
  196.     {
  197.         wxPanel* panel = new wxPanel(this, wxID_ANY);
  198.         TestBox* list = new TestBox(panel, wxID_ANY);
  199.         for(int i = 0; i < 500; i++) {
  200.             list->appendToList(wxString::Format("%d - testtesttesttesttesttesttesttest", i), list->GetCount());
  201.         }
  202.         list->SetSelection(0);
  203.         Centre();
  204.     }
  205. };
  206.  
  207. class TestApp : public wxApp
  208. {
  209. public:
  210.     bool OnInit()
  211.     {
  212.         TestFrame* window = new TestFrame("Test");
  213.         SetTopWindow(window);
  214.         window->Centre();
  215.         window->Show();
  216.         return true;
  217.     }
  218. };
  219.  
  220. DECLARE_APP(TestApp);
  221. IMPLEMENT_APP(TestApp);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement