CustomListView.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "CustomListView.h"
  2. #include "AutoConnect.h"
  3. #include "UserInterfaceUtility.h"
  4. #include <QEvent>
  5. #include <QMouseEvent>
  6. #include <QScrollBar>
  7. #include <QPoint>
  8. #include <QTimer>
  9. class CustomListViewPrivate
  10. {
  11. public:
  12. explicit CustomListViewPrivate(CustomListView* parent);
  13. ~CustomListViewPrivate();
  14. void initializeTimer();
  15. QPoint m_StartMovePoint;
  16. int m_Threshold;
  17. bool m_Filter;
  18. bool m_LongPressFilter;
  19. QTimer* m_Timer;
  20. private:
  21. CustomListView* m_Parent;
  22. };
  23. CustomListView::CustomListView(QWidget *parent, const bool tansparent)
  24. : QListView(parent)
  25. , m_Private(new CustomListViewPrivate(this))
  26. {
  27. if (tansparent) {
  28. QPalette palette = this->palette();
  29. palette.setBrush(QPalette::Base, QBrush(Qt::NoBrush));
  30. setPalette(palette);
  31. }
  32. setFrameShape(QListView::NoFrame);
  33. setVerticalScrollMode(QListView::ScrollPerPixel);
  34. setEditTriggers(QListView::NoEditTriggers);
  35. setSpacing(0);
  36. setDragEnabled(false);
  37. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  38. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  39. setSelectionBehavior(QListView::SelectRows);
  40. setSelectionMode(QListView::SingleSelection);
  41. }
  42. CustomListView::~CustomListView()
  43. {
  44. }
  45. void CustomListView::setCurrentIndex(const QModelIndex &index)
  46. {
  47. QListView::setCurrentIndex(index);
  48. onCurrentIndexChange(index);
  49. if (isVisible()) {
  50. update();
  51. }
  52. }
  53. void CustomListView::setItemDelegate(QAbstractItemDelegate *delegate)
  54. {
  55. connectSignalAndSlotByNamesake(this, delegate, SLOT(onPressIndexChanged(const QModelIndex &)));
  56. connectSignalAndSlotByNamesake(this, delegate, SLOT(onCurrentIndexChange(const QModelIndex &)));
  57. QListView::setItemDelegate(delegate);
  58. }
  59. void CustomListView::enableLongPress(const bool flag)
  60. {
  61. if (flag) {
  62. m_Private->initializeTimer();
  63. }
  64. }
  65. void CustomListView::mousePressEvent(QMouseEvent *event)
  66. {
  67. m_Private->m_StartMovePoint = event->pos();
  68. m_Private->m_Filter = false;
  69. m_Private->m_LongPressFilter = false;
  70. QModelIndex modelIndex = indexAt(event->pos());
  71. if (modelIndex.isValid()) {
  72. emit onPressIndexChanged(modelIndex);
  73. update(modelIndex);
  74. if (NULL != m_Private->m_Timer) {
  75. m_Private->m_Timer->start();
  76. }
  77. }
  78. QListView::mousePressEvent(event);
  79. }
  80. void CustomListView::mouseMoveEvent(QMouseEvent *event)
  81. {
  82. if (!m_Private->m_LongPressFilter) {
  83. QPoint relativePos = m_Private->m_StartMovePoint - event->pos();
  84. int deltaEnd = 0;
  85. if (QListView::LeftToRight == flow()) {
  86. deltaEnd = event->pos().x() - m_Private->m_StartMovePoint.x();
  87. } else {
  88. deltaEnd = event->pos().y() - m_Private->m_StartMovePoint.y();
  89. }
  90. if (m_Private->m_Filter) {
  91. m_Private->m_StartMovePoint = event->pos();
  92. if (QListView::LeftToRight == flow()) {
  93. horizontalScrollBar()->setValue(horizontalOffset() + relativePos.x());
  94. } else {
  95. verticalScrollBar()->setValue(verticalOffset() + relativePos.y());
  96. }
  97. } else if ((qAbs(deltaEnd) > m_Private->m_Threshold)) {
  98. if (NULL != m_Private->m_Timer) {
  99. m_Private->m_Timer->stop();
  100. }
  101. emit onPressIndexChanged(QModelIndex());
  102. if (isVisible()) {
  103. update();
  104. }
  105. m_Private->m_Filter = true;
  106. m_Private->m_StartMovePoint = event->pos();
  107. if (QListView::LeftToRight == flow()) {
  108. if (relativePos.x() > 0) {
  109. horizontalScrollBar()->setValue(horizontalOffset() + relativePos.x() - m_Private->m_Threshold);
  110. } else {
  111. horizontalScrollBar()->setValue(horizontalOffset() + relativePos.x() + m_Private->m_Threshold);
  112. }
  113. } else {
  114. if (relativePos.y() > 0) {
  115. verticalScrollBar()->setValue(verticalOffset() + relativePos.y() - m_Private->m_Threshold);
  116. } else {
  117. verticalScrollBar()->setValue(verticalOffset() + relativePos.y() + m_Private->m_Threshold);
  118. }
  119. }
  120. }
  121. }
  122. QListView::mouseReleaseEvent(event);
  123. }
  124. void CustomListView::mouseReleaseEvent(QMouseEvent *event)
  125. {
  126. if (!m_Private->m_LongPressFilter) {
  127. if (NULL != m_Private->m_Timer) {
  128. m_Private->m_Timer->stop();
  129. }
  130. if (!m_Private->m_Filter) {
  131. QModelIndex modelIndex = indexAt(event->pos());
  132. if (modelIndex.isValid()) {
  133. emit listViewItemRelease(modelIndex.row());
  134. }
  135. }
  136. }
  137. emit onPressIndexChanged(QModelIndex());
  138. if (isVisible()) {
  139. update();
  140. }
  141. m_Private->m_Filter = false;
  142. emit listViewRelease();
  143. QListView::mouseReleaseEvent(event);
  144. }
  145. void CustomListView::onTimeout()
  146. {
  147. m_Private->m_LongPressFilter = true;
  148. QModelIndex modelIndex = indexAt(m_Private->m_StartMovePoint);
  149. if (modelIndex.isValid()) {
  150. emit listViewItemLongPress(modelIndex.row());
  151. }
  152. }
  153. CustomListViewPrivate::CustomListViewPrivate(CustomListView *parent)
  154. : m_Parent(parent)
  155. {
  156. m_StartMovePoint = QPoint(0, 0);
  157. m_Threshold = 10;
  158. m_Filter = false;
  159. m_LongPressFilter = false;
  160. m_Timer = NULL;
  161. }
  162. CustomListViewPrivate::~CustomListViewPrivate()
  163. {
  164. }
  165. void CustomListViewPrivate::initializeTimer()
  166. {
  167. if (NULL == m_Timer) {
  168. m_Timer = new QTimer(m_Parent);
  169. m_Timer->setSingleShot(true);
  170. m_Timer->setInterval(1000);
  171. QObject::connect(m_Timer, SIGNAL(timeout()),
  172. m_Parent, SLOT(onTimeout()));
  173. }
  174. }