MixWithComboxInput.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "MixWithComboxInput.h"
  2. #include <QComboBox>
  3. #include <QLabel>
  4. #include <QHBoxLayout>
  5. #include <QPainter>
  6. #include <QAbstractItemView>
  7. #include <QKeyEvent>
  8. class MixWithComboxInput::Private
  9. {
  10. public:
  11. QComboBox *combo;
  12. QLabel *label;
  13. bool inside;
  14. bool isFlat;
  15. };
  16. MixWithComboxInput::MixWithComboxInput(QWidget *parent) : QStackedWidget(parent), d(new Private)
  17. {
  18. #ifdef Q_OS_MACOS
  19. setAttribute(Qt::WA_MacMiniSize, true);
  20. #endif
  21. QWidget *first = new QWidget(this);
  22. QHBoxLayout *layout = new QHBoxLayout(first);
  23. layout->setSpacing(0);
  24. layout->setMargin(0);
  25. d->label = new QLabel(first);
  26. d->label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
  27. layout->addWidget(d->label, 10);
  28. QLabel *icon = new QLabel(first);
  29. QStyleOption option;
  30. option.state = QStyle::State_Enabled;
  31. QPixmap pixmap(16, 16);
  32. pixmap.fill(QColor(255, 255, 255, 0));
  33. QPainter painter(&pixmap);
  34. painter.translate(8, 8);
  35. style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter);
  36. icon->setPixmap(pixmap);
  37. layout->addWidget(icon);
  38. addWidget(first);
  39. d->combo = new QComboBox(this);
  40. d->combo->setMaxVisibleItems(15);
  41. d->combo->setEditable(true);
  42. d->combo->installEventFilter(this);
  43. addWidget(d->combo);
  44. d->inside = false;
  45. d->isFlat = true;
  46. connect(d->combo, SIGNAL(activated(QString)), this, SIGNAL(inputLevelChanged(QString)));
  47. }
  48. MixWithComboxInput::~MixWithComboxInput()
  49. {
  50. delete d;
  51. }
  52. void MixWithComboxInput::enterEvent(QEvent *event)
  53. {
  54. Q_UNUSED(event);
  55. d->inside = true;
  56. if (!isFlat()) {
  57. return;
  58. }
  59. if (d->combo->view()) {
  60. d->combo->view()->removeEventFilter(this);
  61. }
  62. setCurrentIndex(1);
  63. }
  64. void MixWithComboxInput::leaveEvent(QEvent *event)
  65. {
  66. Q_UNUSED(event);
  67. d->inside = false;
  68. if (!isFlat()) {
  69. return;
  70. }
  71. if (d->combo->view() && d->combo->view()->isVisible()) {
  72. d->combo->view()->installEventFilter(this);
  73. return;
  74. }
  75. if (!d->combo->hasFocus())
  76. setCurrentIndex(0);
  77. }
  78. void MixWithComboxInput::keyPressEvent(QKeyEvent *event)
  79. {
  80. if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
  81. focusNextChild();
  82. }
  83. }
  84. bool MixWithComboxInput::isFlat() const
  85. {
  86. return d->isFlat;
  87. }
  88. void MixWithComboxInput::setFlat(bool flat)
  89. {
  90. if (flat == d->isFlat) {
  91. return;
  92. }
  93. d->isFlat = flat;
  94. if (flat) {
  95. d->combo->installEventFilter(this);
  96. if (d->inside) {
  97. enterEvent(nullptr);
  98. } else {
  99. leaveEvent(nullptr);
  100. }
  101. d->combo->setEditable(true);
  102. } else {
  103. d->combo->removeEventFilter(this);
  104. if (d->combo->view()) {
  105. d->combo->view()->removeEventFilter(this);
  106. }
  107. d->combo->setCurrentIndex(d->combo->findText(d->label->text()));
  108. d->combo->setEditable(false);
  109. setCurrentIndex(1);
  110. }
  111. }
  112. void MixWithComboxInput::setInputLevels(const QStringList &levels)
  113. {
  114. d->combo->clear();
  115. d->combo->addItems(levels);
  116. }
  117. QString MixWithComboxInput::currentInputLevel() const
  118. {
  119. return d->label->text();
  120. }
  121. void MixWithComboxInput::setCurrentInputLevel(const QString &level)
  122. {
  123. d->combo->setCurrentIndex(d->combo->findText(level));
  124. d->label->setText(level);
  125. }
  126. bool MixWithComboxInput::eventFilter(QObject *watched, QEvent *event)
  127. {
  128. if (watched == d->combo->view() && event->type() == QEvent::Hide) {
  129. focusNextChild();
  130. setCurrentIndex(0);
  131. } else if (watched == d->combo && event->type() == QEvent::FocusOut
  132. && (d->combo->view() && !d->combo->view()->hasFocus()) && !d->inside) {
  133. setCurrentIndex(0);
  134. }
  135. return false;
  136. }