You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.4KB

  1. #include "widgets.hpp"
  2. // for gVg
  3. #include "gui.hpp"
  4. // for key codes
  5. #include <GLFW/glfw3.h>
  6. namespace rack {
  7. void TextField::draw(NVGcontext *vg) {
  8. BNDwidgetState state;
  9. if (this == gFocusedWidget)
  10. state = BND_ACTIVE;
  11. else if (this == gHoveredWidget)
  12. state = BND_HOVER;
  13. else
  14. state = BND_DEFAULT;
  15. bndTextField(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE, state, -1, text.c_str(), begin, end);
  16. if (text.empty() && state != BND_ACTIVE) {
  17. bndIconLabelCaret(vg, 0.0, 0.0, box.size.x, box.size.y, -1, bndGetTheme()->textFieldTheme.itemColor, 13, placeholder.c_str(), bndGetTheme()->textFieldTheme.itemColor, 0, -1);
  18. }
  19. }
  20. Widget *TextField::onMouseDown(Vec pos, int button) {
  21. end = begin = bndTextFieldTextPosition(gVg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), pos.x, pos.y);
  22. return OpaqueWidget::onMouseDown(pos, button);
  23. }
  24. bool TextField::onFocusText(int codepoint) {
  25. char c = codepoint;
  26. std::string newText(1, c);
  27. insertText(newText);
  28. return true;
  29. }
  30. bool TextField::onFocusKey(int key) {
  31. switch (key) {
  32. case GLFW_KEY_BACKSPACE:
  33. if (begin < end) {
  34. text.erase(begin, end - begin);
  35. }
  36. else {
  37. begin--;
  38. if (begin >= 0)
  39. text.erase(begin, 1);
  40. }
  41. end = begin;
  42. break;
  43. case GLFW_KEY_DELETE:
  44. if (begin < end) {
  45. text.erase(begin, end - begin);
  46. }
  47. else {
  48. text.erase(begin, 1);
  49. }
  50. end = begin;
  51. break;
  52. case GLFW_KEY_LEFT:
  53. if (begin < end) {
  54. }
  55. else {
  56. begin--;
  57. }
  58. end = begin;
  59. break;
  60. case GLFW_KEY_RIGHT:
  61. if (begin < end) {
  62. begin = end;
  63. }
  64. else {
  65. begin++;
  66. }
  67. end = begin;
  68. break;
  69. case GLFW_KEY_HOME:
  70. end = begin = 0;
  71. break;
  72. case GLFW_KEY_END:
  73. end = begin = text.size();
  74. break;
  75. case GLFW_KEY_V:
  76. if (guiIsModPressed()) {
  77. const char *newText = glfwGetClipboardString(gWindow);
  78. if (newText)
  79. insertText(newText);
  80. }
  81. break;
  82. case GLFW_KEY_C:
  83. if (guiIsModPressed()) {
  84. if (begin < end) {
  85. std::string selectedText = text.substr(begin, end - begin);
  86. glfwSetClipboardString(gWindow, selectedText.c_str());
  87. }
  88. }
  89. break;
  90. }
  91. begin = mini(maxi(begin, 0), text.size());
  92. end = mini(maxi(end, 0), text.size());
  93. return true;
  94. }
  95. bool TextField::onFocus() {
  96. begin = 0;
  97. end = text.size();
  98. return true;
  99. }
  100. void TextField::insertText(std::string newText) {
  101. if (begin < end)
  102. text.erase(begin, end - begin);
  103. text.insert(begin, newText);
  104. begin += newText.size();
  105. end = begin;
  106. }
  107. } // namespace rack