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.

164 lines
3.9KB

  1. #include "app.hpp"
  2. #include "engine.hpp"
  3. namespace rack {
  4. static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) {
  5. NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);
  6. // Plug solid
  7. nvgBeginPath(vg);
  8. nvgCircle(vg, pos.x, pos.y, 9.5);
  9. nvgFillColor(vg, color);
  10. nvgFill(vg);
  11. // Border
  12. nvgStrokeWidth(vg, 1.0);
  13. nvgStrokeColor(vg, colorOutline);
  14. nvgStroke(vg);
  15. // Hole
  16. nvgBeginPath(vg);
  17. nvgCircle(vg, pos.x, pos.y, 5.5);
  18. nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0));
  19. nvgFill(vg);
  20. }
  21. static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) {
  22. NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08);
  23. NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5);
  24. // Wire
  25. if (opacity > 0.0) {
  26. nvgSave(vg);
  27. nvgGlobalAlpha(vg, powf(opacity, 1.5));
  28. float dist = pos1.minus(pos2).norm();
  29. Vec slump;
  30. slump.y = (1.0 - tension) * (150.0 + 1.0*dist);
  31. Vec pos3 = pos1.plus(pos2).div(2).plus(slump);
  32. nvgLineJoin(vg, NVG_ROUND);
  33. // Shadow
  34. Vec pos4 = pos3.plus(slump.mult(0.08));
  35. nvgBeginPath(vg);
  36. nvgMoveTo(vg, pos1.x, pos1.y);
  37. nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y);
  38. nvgStrokeColor(vg, colorShadow);
  39. nvgStrokeWidth(vg, 5);
  40. nvgStroke(vg);
  41. // Wire outline
  42. nvgBeginPath(vg);
  43. nvgMoveTo(vg, pos1.x, pos1.y);
  44. nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y);
  45. nvgStrokeColor(vg, colorOutline);
  46. nvgStrokeWidth(vg, 5);
  47. nvgStroke(vg);
  48. // Wire solid
  49. nvgStrokeColor(vg, color);
  50. nvgStrokeWidth(vg, 3);
  51. nvgStroke(vg);
  52. nvgRestore(vg);
  53. }
  54. }
  55. static const NVGcolor wireColors[8] = {
  56. nvgRGB(0xc9, 0xb7, 0x0e), // yellow
  57. nvgRGB(0xc9, 0x18, 0x47), // red
  58. nvgRGB(0x0c, 0x8e, 0x15), // green
  59. nvgRGB(0x09, 0x86, 0xad), // blue
  60. nvgRGB(0x44, 0x44, 0x44), // black
  61. nvgRGB(0x66, 0x66, 0x66), // gray
  62. nvgRGB(0x88, 0x88, 0x88), // light gray
  63. nvgRGB(0xaa, 0xaa, 0xaa), // white
  64. };
  65. static int lastWireColorId = -1;
  66. WireWidget::WireWidget() {
  67. lastWireColorId = (lastWireColorId + 1) % 8;
  68. color = wireColors[lastWireColorId];
  69. }
  70. WireWidget::~WireWidget() {
  71. if (outputPort) {
  72. outputPort->connectedWire = NULL;
  73. outputPort = NULL;
  74. }
  75. if (inputPort) {
  76. inputPort->connectedWire = NULL;
  77. inputPort = NULL;
  78. }
  79. updateWire();
  80. }
  81. void WireWidget::updateWire() {
  82. if (wire) {
  83. engineRemoveWire(wire);
  84. delete wire;
  85. wire = NULL;
  86. }
  87. if (inputPort && outputPort) {
  88. // Check correct types
  89. assert(inputPort->type == Port::INPUT);
  90. assert(outputPort->type == Port::OUTPUT);
  91. wire = new Wire();
  92. wire->outputModule = outputPort->module;
  93. wire->outputId = outputPort->portId;
  94. wire->inputModule = inputPort->module;
  95. wire->inputId = inputPort->portId;
  96. engineAddWire(wire);
  97. }
  98. }
  99. void WireWidget::draw(NVGcontext *vg) {
  100. Vec absolutePos = getAbsolutePos().minus(box.pos);
  101. float opacity = dynamic_cast<RackScene*>(gScene)->toolbar->wireOpacitySlider->value / 100.0;
  102. float tension = dynamic_cast<RackScene*>(gScene)->toolbar->wireTensionSlider->value;
  103. // Display the actively dragged wire as opaque
  104. if (gRackWidget->activeWire == this)
  105. opacity = 1.0;
  106. // Compute location of outputPos and inputPos
  107. Vec outputPos;
  108. if (outputPort) {
  109. outputPos = Rect(outputPort->getAbsolutePos(), outputPort->box.size).getCenter();
  110. }
  111. else if (hoveredOutputPort) {
  112. outputPos = Rect(hoveredOutputPort->getAbsolutePos(), hoveredOutputPort->box.size).getCenter();
  113. }
  114. else {
  115. outputPos = gMousePos;
  116. }
  117. Vec inputPos;
  118. if (inputPort) {
  119. inputPos = Rect(inputPort->getAbsolutePos(), inputPort->box.size).getCenter();
  120. }
  121. else if (hoveredInputPort) {
  122. inputPos = Rect(hoveredInputPort->getAbsolutePos(), hoveredInputPort->box.size).getCenter();
  123. }
  124. else {
  125. inputPos = gMousePos;
  126. }
  127. outputPos = outputPos.minus(absolutePos);
  128. inputPos = inputPos.minus(absolutePos);
  129. drawWire(vg, outputPos, inputPos, color, tension, opacity);
  130. drawPlug(vg, outputPos, color);
  131. drawPlug(vg, inputPos, color);
  132. }
  133. } // namespace rack