vtoolbox.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "vtoolbox.h"
  2. #include <QPushButton>
  3. #include <QStackedLayout>
  4. #include <QHBoxLayout>
  5. #include <QVBoxLayout>
  6. #include <QVariant>
  7. #include <QLabel>
  8. #include "vnote.h"
  9. #include "utils/vutils.h"
  10. #include "utils/viconutils.h"
  11. extern VNote *g_vnote;
  12. VToolBox::VToolBox(QWidget *p_parent)
  13. : QWidget(p_parent),
  14. m_currentIndex(-1)
  15. {
  16. setupUI();
  17. }
  18. void VToolBox::setupUI()
  19. {
  20. m_btnLayout = new QHBoxLayout();
  21. m_btnLayout->addStretch();
  22. m_btnLayout->setContentsMargins(0, 0, 0, 2);
  23. m_btnLayout->setSpacing(0);
  24. QWidget *wid = new QWidget();
  25. wid->setProperty("ToolBoxTitle", true);
  26. wid->setLayout(m_btnLayout);
  27. m_widgetLayout = new QStackedLayout();
  28. QVBoxLayout *mainLayout = new QVBoxLayout();
  29. mainLayout->addWidget(wid);
  30. mainLayout->addLayout(m_widgetLayout);
  31. int margin = 2 * VUtils::calculateScaleFactor();
  32. mainLayout->setContentsMargins(margin, 0, margin, 0);
  33. setLayout(mainLayout);
  34. }
  35. int VToolBox::addItem(QWidget *p_widget,
  36. const QString &p_iconFile,
  37. const QString &p_text,
  38. QWidget *p_focusWidget)
  39. {
  40. int idx = m_items.size();
  41. // New a button.
  42. QIcon icon = VIconUtils::toolBoxIcon(p_iconFile);
  43. QPushButton *btn = new QPushButton(icon, "");
  44. btn->setToolTip(p_text);
  45. btn->setProperty("FlatBtn", true);
  46. btn->setProperty("ToolBoxTitleBtn", true);
  47. connect(btn, &QPushButton::clicked,
  48. this, [this]() {
  49. QObject *btn = sender();
  50. for (int i = 0; i < m_items.size(); ++i) {
  51. if (m_items[i].m_btn == btn) {
  52. setCurrentIndex(i);
  53. break;
  54. }
  55. }
  56. });
  57. m_btnLayout->insertWidget(idx, btn);
  58. // Insert widget to layout.
  59. m_widgetLayout->insertWidget(idx, p_widget);
  60. m_items.push_back(ItemInfo(p_widget,
  61. p_focusWidget,
  62. p_text,
  63. btn,
  64. icon,
  65. VIconUtils::toolBoxActiveIcon(p_iconFile)));
  66. if (m_items.size() == 1) {
  67. setCurrentIndex(0);
  68. }
  69. return idx;
  70. }
  71. void VToolBox::setCurrentIndex(int p_idx, bool p_focus)
  72. {
  73. if (p_idx < 0 || p_idx >= m_items.size()) {
  74. if (m_items.isEmpty()) {
  75. m_currentIndex = -1;
  76. } else {
  77. m_currentIndex = 0;
  78. }
  79. } else {
  80. m_currentIndex = p_idx;
  81. }
  82. setCurrentButtonIndex(m_currentIndex);
  83. m_widgetLayout->setCurrentIndex(m_currentIndex);
  84. QWidget *widget = m_widgetLayout->widget(m_currentIndex);
  85. if (widget && p_focus) {
  86. if (m_items[m_currentIndex].m_focusWidget) {
  87. m_items[m_currentIndex].m_focusWidget->setFocus();
  88. } else {
  89. widget->setFocus();
  90. }
  91. }
  92. }
  93. void VToolBox::setCurrentWidget(QWidget *p_widget, bool p_focus)
  94. {
  95. int idx = -1;
  96. for (int i = 0; i < m_items.size(); ++i) {
  97. if (m_items[i].m_widget == p_widget) {
  98. idx = i;
  99. break;
  100. }
  101. }
  102. setCurrentIndex(idx, p_focus);
  103. }
  104. void VToolBox::setCurrentButtonIndex(int p_idx)
  105. {
  106. // Remove the text of all button.
  107. for (int i = 0; i < m_items.size(); ++i) {
  108. QPushButton *btn = m_items[i].m_btn;
  109. btn->setText("");
  110. btn->setIcon(m_items[i].m_icon);
  111. btn->clearFocus();
  112. VUtils::setDynamicProperty(btn, "ToolBoxActiveBtn", false);
  113. }
  114. if (p_idx < 0 || p_idx >= m_items.size()) {
  115. return;
  116. }
  117. QPushButton *curBtn = m_items[p_idx].m_btn;
  118. curBtn->setText(m_items[p_idx].m_text);
  119. curBtn->setIcon(m_items[p_idx].m_activeIcon);
  120. VUtils::setDynamicProperty(curBtn, "ToolBoxActiveBtn", true);
  121. }
  122. void VToolBox::showNavigation()
  123. {
  124. clearNavigation();
  125. if (!isVisible()) {
  126. return;
  127. }
  128. for (int i = 0; i < 26 && i < m_items.size(); ++i) {
  129. const ItemInfo &item = m_items[i];
  130. QChar key('a' + i);
  131. m_keyMap[key] = item.m_widget;
  132. QString str = QString(m_majorKey) + key;
  133. QLabel *label = new QLabel(str, this);
  134. label->setStyleSheet(g_vnote->getNavigationLabelStyle(str));
  135. label->show();
  136. QRect rect = item.m_btn->geometry();
  137. // Display the label at the end to show the file name.
  138. label->move(rect.x(), rect.y() + rect.height() / 2);
  139. m_naviLabels.append(label);
  140. }
  141. }
  142. bool VToolBox::handleKeyNavigation(int p_key, bool &p_succeed)
  143. {
  144. bool ret = false;
  145. p_succeed = false;
  146. QChar keyChar = VUtils::keyToChar(p_key);
  147. if (m_isSecondKey && !keyChar.isNull()) {
  148. m_isSecondKey = false;
  149. p_succeed = true;
  150. auto it = m_keyMap.find(keyChar);
  151. if (it != m_keyMap.end()) {
  152. ret = true;
  153. QWidget *widget = static_cast<QWidget *>(it.value());
  154. setCurrentWidget(widget);
  155. }
  156. } else if (keyChar == m_majorKey) {
  157. // Major key pressed.
  158. // Need second key if m_keyMap is not empty.
  159. if (m_keyMap.isEmpty()) {
  160. p_succeed = true;
  161. } else {
  162. m_isSecondKey = true;
  163. }
  164. ret = true;
  165. }
  166. return ret;
  167. }