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.

200 lines
5.1KB

  1. #include <app/LedDisplay.hpp>
  2. #include <asset.hpp>
  3. #include <window/Window.hpp>
  4. #include <context.hpp>
  5. namespace rack {
  6. namespace app {
  7. void LedDisplay::draw(const DrawArgs& args) {
  8. math::Rect r = box.zeroPos();
  9. // Black background
  10. nvgBeginPath(args.vg);
  11. nvgRect(args.vg, RECT_ARGS(r));
  12. NVGcolor topColor = nvgRGB(0x22, 0x22, 0x22);
  13. NVGcolor bottomColor = nvgRGB(0x12, 0x12, 0x12);
  14. nvgFillPaint(args.vg, nvgLinearGradient(args.vg, 0.0, 0.0, 0.0, 25.0, topColor, bottomColor));
  15. // nvgFillColor(args.vg, bottomColor);
  16. nvgFill(args.vg);
  17. // Outer strokes
  18. nvgBeginPath(args.vg);
  19. nvgMoveTo(args.vg, 0.0, -0.5);
  20. nvgLineTo(args.vg, box.size.x, -0.5);
  21. nvgStrokeColor(args.vg, nvgRGBAf(0, 0, 0, 0.24));
  22. nvgStrokeWidth(args.vg, 1.0);
  23. nvgStroke(args.vg);
  24. nvgBeginPath(args.vg);
  25. nvgMoveTo(args.vg, 0.0, box.size.y + 0.5);
  26. nvgLineTo(args.vg, box.size.x, box.size.y + 0.5);
  27. nvgStrokeColor(args.vg, nvgRGBAf(1, 1, 1, 0.30));
  28. nvgStrokeWidth(args.vg, 1.0);
  29. nvgStroke(args.vg);
  30. // Inner strokes
  31. nvgBeginPath(args.vg);
  32. nvgMoveTo(args.vg, 0.0, 2.5);
  33. nvgLineTo(args.vg, box.size.x, 2.5);
  34. nvgStrokeColor(args.vg, nvgRGBAf(1, 1, 1, 0.20));
  35. nvgStrokeWidth(args.vg, 1.0);
  36. nvgStroke(args.vg);
  37. nvgBeginPath(args.vg);
  38. nvgMoveTo(args.vg, 0.0, box.size.y - 2.5);
  39. nvgLineTo(args.vg, box.size.x, box.size.y - 2.5);
  40. nvgStrokeColor(args.vg, nvgRGBAf(1, 1, 1, 0.20));
  41. nvgStrokeWidth(args.vg, 1.0);
  42. nvgStroke(args.vg);
  43. // Black border
  44. math::Rect rBorder = r.shrink(math::Vec(1, 1));
  45. nvgBeginPath(args.vg);
  46. nvgRect(args.vg, RECT_ARGS(rBorder));
  47. nvgStrokeColor(args.vg, bottomColor);
  48. nvgStrokeWidth(args.vg, 2.0);
  49. nvgStroke(args.vg);
  50. // Draw children inside box
  51. nvgScissor(args.vg, RECT_ARGS(args.clipBox));
  52. Widget::draw(args);
  53. nvgResetScissor(args.vg);
  54. }
  55. void LedDisplay::drawLayer(const DrawArgs& args, int layer) {
  56. // Draw children inside box
  57. nvgScissor(args.vg, RECT_ARGS(args.clipBox));
  58. Widget::drawLayer(args, layer);
  59. nvgResetScissor(args.vg);
  60. }
  61. LedDisplaySeparator::LedDisplaySeparator() {
  62. box.size = math::Vec();
  63. }
  64. void LedDisplaySeparator::draw(const DrawArgs& args) {
  65. nvgBeginPath(args.vg);
  66. nvgMoveTo(args.vg, 0, 0);
  67. nvgLineTo(args.vg, box.size.x, box.size.y);
  68. nvgStrokeWidth(args.vg, 1.0);
  69. nvgStrokeColor(args.vg, nvgRGB(0x33, 0x33, 0x33));
  70. nvgStroke(args.vg);
  71. }
  72. LedDisplayChoice::LedDisplayChoice() {
  73. box.size = window::mm2px(math::Vec(0, 28.0 / 3));
  74. fontPath = asset::system("res/fonts/ShareTechMono-Regular.ttf");
  75. textOffset = math::Vec(10, 18);
  76. color = nvgRGB(0xff, 0xd7, 0x14);
  77. bgColor = nvgRGBAf(0, 0, 0, 0);
  78. }
  79. void LedDisplayChoice::draw(const DrawArgs& args) {
  80. if (bgColor.a > 0.0) {
  81. nvgBeginPath(args.vg);
  82. nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
  83. nvgFillColor(args.vg, bgColor);
  84. nvgFill(args.vg);
  85. }
  86. Widget::draw(args);
  87. }
  88. void LedDisplayChoice::drawLayer(const DrawArgs& args, int layer) {
  89. nvgScissor(args.vg, RECT_ARGS(args.clipBox));
  90. if (layer == 1) {
  91. std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
  92. if (font && font->handle >= 0) {
  93. nvgFillColor(args.vg, color);
  94. nvgFontFaceId(args.vg, font->handle);
  95. nvgTextLetterSpacing(args.vg, 0.0);
  96. nvgFontSize(args.vg, 12);
  97. nvgText(args.vg, textOffset.x, textOffset.y, text.c_str(), NULL);
  98. }
  99. }
  100. Widget::drawLayer(args, layer);
  101. nvgResetScissor(args.vg);
  102. }
  103. void LedDisplayChoice::onButton(const ButtonEvent& e) {
  104. OpaqueWidget::onButton(e);
  105. if (e.action == GLFW_PRESS && (e.button == GLFW_MOUSE_BUTTON_LEFT || e.button == GLFW_MOUSE_BUTTON_RIGHT)) {
  106. ActionEvent eAction;
  107. onAction(eAction);
  108. e.consume(this);
  109. }
  110. }
  111. LedDisplayTextField::LedDisplayTextField() {
  112. fontPath = asset::system("res/fonts/ShareTechMono-Regular.ttf");
  113. textOffset = math::Vec(5, 5);
  114. color = nvgRGB(0xff, 0xd7, 0x14);
  115. bgColor = nvgRGB(0x00, 0x00, 0x00);
  116. }
  117. void LedDisplayTextField::draw(const DrawArgs& args) {
  118. Widget::draw(args);
  119. }
  120. void LedDisplayTextField::drawLayer(const DrawArgs& args, int layer) {
  121. nvgScissor(args.vg, RECT_ARGS(args.clipBox));
  122. if (layer == 1) {
  123. // Text
  124. std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
  125. if (font && font->handle >= 0) {
  126. bndSetFont(font->handle);
  127. NVGcolor highlightColor = color;
  128. highlightColor.a = 0.5;
  129. int begin = std::min(cursor, selection);
  130. int end = (this == APP->event->selectedWidget) ? std::max(cursor, selection) : -1;
  131. bndIconLabelCaret(args.vg,
  132. textOffset.x, textOffset.y,
  133. box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
  134. -1, color, 12, text.c_str(), highlightColor, begin, end);
  135. bndSetFont(APP->window->uiFont->handle);
  136. }
  137. }
  138. Widget::drawLayer(args, layer);
  139. nvgResetScissor(args.vg);
  140. }
  141. int LedDisplayTextField::getTextPosition(math::Vec mousePos) {
  142. std::shared_ptr<window::Font> font = APP->window->loadFont(fontPath);
  143. if (!font || !font->handle)
  144. return 0;
  145. bndSetFont(font->handle);
  146. int textPos = bndIconLabelTextPosition(APP->window->vg,
  147. textOffset.x, textOffset.y,
  148. box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
  149. -1, 12, text.c_str(), mousePos.x, mousePos.y);
  150. bndSetFont(APP->window->uiFont->handle);
  151. return textPos;
  152. }
  153. } // namespace app
  154. } // namespace rack