@@ -1,3 +1,6 @@ | |||||
[submodule "ext/nanovg"] | [submodule "ext/nanovg"] | ||||
path = ext/nanovg | path = ext/nanovg | ||||
url = https://github.com/memononen/nanovg.git | url = https://github.com/memononen/nanovg.git | ||||
[submodule "ext/nanosvg"] | |||||
path = ext/nanosvg | |||||
url = https://github.com/memononen/nanosvg.git |
@@ -0,0 +1 @@ | |||||
Subproject commit dc12d90586a8ab99da0c575aafff999666aa5d55 |
@@ -166,18 +166,18 @@ ParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, f | |||||
return param; | return param; | ||||
} | } | ||||
inline | |||||
template <class TInputPort> | |||||
InputPort *createInput(Vec pos, Module *module, int inputId) { | InputPort *createInput(Vec pos, Module *module, int inputId) { | ||||
InputPort *port = new InputPort(); | |||||
InputPort *port = new TInputPort(); | |||||
port->box.pos = pos; | port->box.pos = pos; | ||||
port->module = module; | port->module = module; | ||||
port->inputId = inputId; | port->inputId = inputId; | ||||
return port; | return port; | ||||
} | } | ||||
inline | |||||
template <class TOutputPort> | |||||
OutputPort *createOutput(Vec pos, Module *module, int outputId) { | OutputPort *createOutput(Vec pos, Module *module, int outputId) { | ||||
OutputPort *port = new OutputPort(); | |||||
OutputPort *port = new TOutputPort(); | |||||
port->box.pos = pos; | port->box.pos = pos; | ||||
port->module = module; | port->module = module; | ||||
port->outputId = outputId; | port->outputId = outputId; | ||||
@@ -94,7 +94,6 @@ struct RackWidget : OpaqueWidget { | |||||
struct ModulePanel : TransparentWidget { | struct ModulePanel : TransparentWidget { | ||||
NVGcolor backgroundColor; | NVGcolor backgroundColor; | ||||
NVGcolor highlightColor; | |||||
std::string imageFilename; | std::string imageFilename; | ||||
void draw(NVGcontext *vg); | void draw(NVGcontext *vg); | ||||
}; | }; | ||||
@@ -167,7 +166,7 @@ struct MomentarySwitch : virtual Switch { | |||||
// ports | // ports | ||||
//////////////////// | //////////////////// | ||||
struct Port : OpaqueWidget, SpriteWidget { | |||||
struct Port : OpaqueWidget { | |||||
Module *module = NULL; | Module *module = NULL; | ||||
WireWidget *connectedWire = NULL; | WireWidget *connectedWire = NULL; | ||||
@@ -175,8 +174,6 @@ struct Port : OpaqueWidget, SpriteWidget { | |||||
~Port(); | ~Port(); | ||||
void disconnect(); | void disconnect(); | ||||
int type; | |||||
void drawGlow(NVGcontext *vg); | |||||
void onMouseDown(int button); | void onMouseDown(int button); | ||||
void onDragEnd(); | void onDragEnd(); | ||||
}; | }; | ||||
@@ -184,7 +181,6 @@ struct Port : OpaqueWidget, SpriteWidget { | |||||
struct InputPort : Port { | struct InputPort : Port { | ||||
int inputId; | int inputId; | ||||
void draw(NVGcontext *vg); | |||||
void onDragStart(); | void onDragStart(); | ||||
void onDragDrop(Widget *origin); | void onDragDrop(Widget *origin); | ||||
}; | }; | ||||
@@ -192,7 +188,6 @@ struct InputPort : Port { | |||||
struct OutputPort : Port { | struct OutputPort : Port { | ||||
int outputId; | int outputId; | ||||
void draw(NVGcontext *vg); | |||||
void onDragStart(); | void onDragStart(); | ||||
void onDragDrop(Widget *origin); | void onDragDrop(Widget *origin); | ||||
}; | }; | ||||
@@ -220,5 +215,41 @@ struct Scene : OpaqueWidget { | |||||
void step(); | void step(); | ||||
}; | }; | ||||
//////////////////// | |||||
// component library | |||||
//////////////////// | |||||
struct PJ301M : SpriteWidget { | |||||
PJ301M() { | |||||
box.size = Vec(24, 24); | |||||
spriteOffset = Vec(-10, -10); | |||||
spriteSize = Vec(48, 48); | |||||
spriteFilename = "res/ComponentLibrary/PJ301M.png"; | |||||
} | |||||
}; | |||||
struct InputPortPJ301M : InputPort, PJ301M {}; | |||||
struct OutputPortPJ301M: OutputPort, PJ301M {}; | |||||
struct PJ3410 : SpriteWidget { | |||||
PJ3410() { | |||||
box.size = Vec(31, 31); | |||||
spriteOffset = Vec(-9, -9); | |||||
spriteSize = Vec(54, 54); | |||||
spriteFilename = "res/ComponentLibrary/PJ3410.png"; | |||||
} | |||||
}; | |||||
struct InputPortPJ3410 : InputPort, PJ3410 {}; | |||||
struct OutputPortPJ3410: OutputPort, PJ3410 {}; | |||||
struct CL1362 : SpriteWidget { | |||||
CL1362() { | |||||
box.size = Vec(33, 29); | |||||
spriteOffset = Vec(-10, -10); | |||||
spriteSize = Vec(57, 54); | |||||
spriteFilename = "res/ComponentLibrary/CL1362.png"; | |||||
} | |||||
}; | |||||
struct InputPortCL1362 : InputPort, CL1362 {}; | |||||
struct OutputPortCL1362 : OutputPort, CL1362 {}; | |||||
} // namespace rack | } // namespace rack |
@@ -45,10 +45,11 @@ struct AudioInterface : Module { | |||||
SampleRateConverter<2> inputSrc; | SampleRateConverter<2> inputSrc; | ||||
SampleRateConverter<2> outputSrc; | SampleRateConverter<2> outputSrc; | ||||
// in device's sample rate | |||||
DoubleRingBuffer<Frame<2>, (1<<15)> inputBuffer; | |||||
// in rack's sample rate | // in rack's sample rate | ||||
DoubleRingBuffer<Frame<2>, 32> inputBuffer; | |||||
DoubleRingBuffer<Frame<2>, (1<<15)> outputBuffer; | DoubleRingBuffer<Frame<2>, (1<<15)> outputBuffer; | ||||
// in device's sample rate | |||||
DoubleRingBuffer<Frame<2>, (1<<15)> inputSrcBuffer; | |||||
AudioInterface(); | AudioInterface(); | ||||
~AudioInterface(); | ~AudioInterface(); | ||||
@@ -89,29 +90,35 @@ void AudioInterface::step() { | |||||
// Get input and pass it through the sample rate converter | // Get input and pass it through the sample rate converter | ||||
if (numOutputs > 0) { | if (numOutputs > 0) { | ||||
Frame<2> f; | |||||
f.samples[0] = getf(inputs[AUDIO1_INPUT]) / 5.0; | |||||
f.samples[1] = getf(inputs[AUDIO2_INPUT]) / 5.0; | |||||
inputSrc.setRatio(sampleRate / gRack->sampleRate); | |||||
int inLen = 1; | |||||
int outLen = inputBuffer.capacity(); | |||||
inputSrc.process((const float*) &f, &inLen, (float*) inputBuffer.endData(), &outLen); | |||||
inputBuffer.endIncr(outLen); | |||||
if (!inputBuffer.full()) { | |||||
Frame<2> f; | |||||
f.samples[0] = getf(inputs[AUDIO1_INPUT]) / 5.0; | |||||
f.samples[1] = getf(inputs[AUDIO2_INPUT]) / 5.0; | |||||
inputBuffer.push(f); | |||||
} | |||||
// Once full, sample rate convert the input | |||||
if (inputBuffer.full()) { | |||||
inputSrc.setRatio(sampleRate / gRack->sampleRate); | |||||
int inLen = inputBuffer.size(); | |||||
int outLen = inputSrcBuffer.capacity(); | |||||
inputSrc.process((const float*) inputBuffer.startData(), &inLen, (float*) inputSrcBuffer.endData(), &outLen); | |||||
inputBuffer.startIncr(inLen); | |||||
inputSrcBuffer.endIncr(outLen); | |||||
} | |||||
} | } | ||||
// Read/write stream if we have enough input | |||||
bool streamReady = (numOutputs > 0) ? (inputBuffer.size() >= blockSize) : (outputBuffer.empty()); | |||||
// Read/write stream if we have enough input, OR the output buffer is empty if we have no input | |||||
bool streamReady = (numOutputs > 0) ? (inputSrcBuffer.size() >= blockSize) : (outputBuffer.empty()); | |||||
if (streamReady) { | if (streamReady) { | ||||
// printf("%p\t%d\t%d\n", this, inputSrcBuffer.size(), outputBuffer.size()); | |||||
PaError err; | PaError err; | ||||
// Read output from input stream | // Read output from input stream | ||||
// (for some reason, if you write the output stream before you read the input stream, PortAudio can segfault on Windows.) | // (for some reason, if you write the output stream before you read the input stream, PortAudio can segfault on Windows.) | ||||
if (numInputs > 0) { | if (numInputs > 0) { | ||||
Frame<2> *buf = new Frame<2>[blockSize]; | Frame<2> *buf = new Frame<2>[blockSize]; | ||||
printf("read %d\n", blockSize); | |||||
err = Pa_ReadStream(stream, (float*) buf, blockSize); | err = Pa_ReadStream(stream, (float*) buf, blockSize); | ||||
printf("read done\n"); | |||||
if (err) { | if (err) { | ||||
// Ignore buffer underflows | // Ignore buffer underflows | ||||
if (err != paInputOverflowed) { | if (err != paInputOverflowed) { | ||||
@@ -131,11 +138,9 @@ void AudioInterface::step() { | |||||
// Write input to output stream | // Write input to output stream | ||||
if (numOutputs > 0) { | if (numOutputs > 0) { | ||||
assert(inputBuffer.size() >= blockSize); | |||||
printf("write %d\n", blockSize); | |||||
err = Pa_WriteStream(stream, (const float*) inputBuffer.startData(), blockSize); | |||||
printf("write done\n"); | |||||
inputBuffer.startIncr(blockSize); | |||||
assert(inputSrcBuffer.size() >= blockSize); | |||||
err = Pa_WriteStream(stream, (const float*) inputSrcBuffer.startData(), blockSize); | |||||
inputSrcBuffer.startIncr(blockSize); | |||||
if (err) { | if (err) { | ||||
// Ignore buffer underflows | // Ignore buffer underflows | ||||
if (err != paOutputUnderflowed) { | if (err != paOutputUnderflowed) { | ||||
@@ -241,6 +246,7 @@ void AudioInterface::closeDevice() { | |||||
// Clear buffers | // Clear buffers | ||||
inputBuffer.clear(); | inputBuffer.clear(); | ||||
outputBuffer.clear(); | outputBuffer.clear(); | ||||
inputSrcBuffer.clear(); | |||||
inputSrc.reset(); | inputSrc.reset(); | ||||
outputSrc.reset(); | outputSrc.reset(); | ||||
} | } | ||||
@@ -355,6 +361,14 @@ struct BlockSizeChoice : ChoiceButton { | |||||
AudioInterfaceWidget::AudioInterfaceWidget() : ModuleWidget(new AudioInterface()) { | AudioInterfaceWidget::AudioInterfaceWidget() : ModuleWidget(new AudioInterface()) { | ||||
box.size = Vec(15*8, 380); | box.size = Vec(15*8, 380); | ||||
{ | |||||
ModulePanel *panel = new ModulePanel(); | |||||
panel->box.size = box.size; | |||||
panel->backgroundColor = nvgRGBf(0.90, 0.90, 0.90); | |||||
// panel->imageFilename = ""; | |||||
addChild(panel); | |||||
} | |||||
float margin = 5; | float margin = 5; | ||||
float yPos = margin; | float yPos = margin; | ||||
@@ -420,8 +434,8 @@ AudioInterfaceWidget::AudioInterfaceWidget() : ModuleWidget(new AudioInterface() | |||||
} | } | ||||
yPos += 5; | yPos += 5; | ||||
addInput(createInput(Vec(25, yPos), module, AudioInterface::AUDIO1_INPUT)); | |||||
addInput(createInput(Vec(75, yPos), module, AudioInterface::AUDIO2_INPUT)); | |||||
addInput(createInput<InputPortPJ3410>(Vec(20, yPos), module, AudioInterface::AUDIO1_INPUT)); | |||||
addInput(createInput<InputPortPJ3410>(Vec(70, yPos), module, AudioInterface::AUDIO2_INPUT)); | |||||
yPos += 35 + margin; | yPos += 35 + margin; | ||||
{ | { | ||||
@@ -433,12 +447,7 @@ AudioInterfaceWidget::AudioInterfaceWidget() : ModuleWidget(new AudioInterface() | |||||
} | } | ||||
yPos += 5; | yPos += 5; | ||||
addOutput(createOutput(Vec(25, yPos), module, AudioInterface::AUDIO1_OUTPUT)); | |||||
addOutput(createOutput(Vec(75, yPos), module, AudioInterface::AUDIO2_OUTPUT)); | |||||
addOutput(createOutput<OutputPortPJ3410>(Vec(20, yPos), module, AudioInterface::AUDIO1_OUTPUT)); | |||||
addOutput(createOutput<OutputPortPJ3410>(Vec(70, yPos), module, AudioInterface::AUDIO2_OUTPUT)); | |||||
yPos += 35 + margin; | yPos += 35 + margin; | ||||
} | } | ||||
void AudioInterfaceWidget::draw(NVGcontext *vg) { | |||||
bndBackground(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); | |||||
ModuleWidget::draw(vg); | |||||
} |
@@ -224,6 +224,14 @@ struct MidiChoice : ChoiceButton { | |||||
MidiInterfaceWidget::MidiInterfaceWidget() : ModuleWidget(new MidiInterface()) { | MidiInterfaceWidget::MidiInterfaceWidget() : ModuleWidget(new MidiInterface()) { | ||||
box.size = Vec(15*8, 380); | box.size = Vec(15*8, 380); | ||||
{ | |||||
ModulePanel *panel = new ModulePanel(); | |||||
panel->box.size = box.size; | |||||
panel->backgroundColor = nvgRGBf(0.90, 0.90, 0.90); | |||||
// panel->imageFilename = ""; | |||||
addChild(panel); | |||||
} | |||||
float margin = 5; | float margin = 5; | ||||
float yPos = margin; | float yPos = margin; | ||||
@@ -246,8 +254,8 @@ MidiInterfaceWidget::MidiInterfaceWidget() : ModuleWidget(new MidiInterface()) { | |||||
} | } | ||||
yPos += 5; | yPos += 5; | ||||
addOutput(createOutput(Vec(25, yPos), module, MidiInterface::PITCH_OUTPUT)); | |||||
addOutput(createOutput(Vec(75, yPos), module, MidiInterface::GATE_OUTPUT)); | |||||
addOutput(createOutput<OutputPortPJ3410>(Vec(20, yPos), module, MidiInterface::PITCH_OUTPUT)); | |||||
addOutput(createOutput<OutputPortPJ3410>(Vec(70, yPos), module, MidiInterface::GATE_OUTPUT)); | |||||
yPos += 25 + margin; | yPos += 25 + margin; | ||||
{ | { | ||||
@@ -264,8 +272,3 @@ MidiInterfaceWidget::MidiInterfaceWidget() : ModuleWidget(new MidiInterface()) { | |||||
yPos += pitchLabel->box.size.y + margin; | yPos += pitchLabel->box.size.y + margin; | ||||
} | } | ||||
} | } | ||||
void MidiInterfaceWidget::draw(NVGcontext *vg) { | |||||
bndBackground(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); | |||||
ModuleWidget::draw(vg); | |||||
} |
@@ -14,10 +14,8 @@ void midiInit(); | |||||
struct AudioInterfaceWidget : ModuleWidget { | struct AudioInterfaceWidget : ModuleWidget { | ||||
AudioInterfaceWidget(); | AudioInterfaceWidget(); | ||||
void draw(NVGcontext *vg); | |||||
}; | }; | ||||
struct MidiInterfaceWidget : ModuleWidget { | struct MidiInterfaceWidget : ModuleWidget { | ||||
MidiInterfaceWidget(); | MidiInterfaceWidget(); | ||||
void draw(NVGcontext *vg); | |||||
}; | }; |
@@ -3,13 +3,6 @@ | |||||
namespace rack { | namespace rack { | ||||
void InputPort::draw(NVGcontext *vg) { | |||||
SpriteWidget::draw(vg); | |||||
if (gRackWidget->activeWire && gRackWidget->activeWire->inputPort) { | |||||
Port::drawGlow(vg); | |||||
} | |||||
} | |||||
void InputPort::onDragStart() { | void InputPort::onDragStart() { | ||||
if (connectedWire) { | if (connectedWire) { | ||||
// Disconnect wire from this port, but set it as the active wire | // Disconnect wire from this port, but set it as the active wire | ||||
@@ -8,12 +8,8 @@ void ModulePanel::draw(NVGcontext *vg) { | |||||
nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); | nvgRect(vg, box.pos.x, box.pos.y, box.size.x, box.size.y); | ||||
NVGpaint paint; | NVGpaint paint; | ||||
// Background gradient | |||||
Vec c = box.pos; | |||||
float length = box.size.norm(); | |||||
paint = nvgRadialGradient(vg, c.x, c.y, 0.0, length, highlightColor, backgroundColor); | |||||
nvgFillPaint(vg, paint); | |||||
// nvgFillColor(vg, backgroundColor); | |||||
// Background color | |||||
nvgFillColor(vg, backgroundColor); | |||||
nvgFill(vg); | nvgFill(vg); | ||||
// Background image | // Background image | ||||
@@ -3,13 +3,6 @@ | |||||
namespace rack { | namespace rack { | ||||
void OutputPort::draw(NVGcontext *vg) { | |||||
SpriteWidget::draw(vg); | |||||
if (gRackWidget->activeWire && gRackWidget->activeWire->outputPort) { | |||||
Port::drawGlow(vg); | |||||
} | |||||
} | |||||
void OutputPort::onDragStart() { | void OutputPort::onDragStart() { | ||||
if (connectedWire) { | if (connectedWire) { | ||||
// Disconnect wire from this port, but set it as the active wire | // Disconnect wire from this port, but set it as the active wire | ||||
@@ -5,11 +5,6 @@ namespace rack { | |||||
Port::Port() { | Port::Port() { | ||||
box.size = Vec(20, 20); | box.size = Vec(20, 20); | ||||
spriteOffset = Vec(-18, -18); | |||||
spriteSize = Vec(56, 56); | |||||
spriteFilename = "res/port.png"; | |||||
index = randomu32() % 5; | |||||
} | } | ||||
Port::~Port() { | Port::~Port() { | ||||
@@ -24,17 +19,6 @@ void Port::disconnect() { | |||||
} | } | ||||
} | } | ||||
void Port::drawGlow(NVGcontext *vg) { | |||||
Vec c = box.getCenter(); | |||||
NVGcolor icol = nvgRGBAf(1, 1, 1, 0.5); | |||||
NVGcolor ocol = nvgRGBAf(1, 1, 1, 0); | |||||
NVGpaint paint = nvgRadialGradient(vg, c.x, c.y, 0, 20, icol, ocol); | |||||
nvgFillPaint(vg, paint); | |||||
nvgBeginPath(vg); | |||||
nvgRect(vg, box.pos.x - 10, box.pos.y - 10, box.size.x + 20, box.size.y + 20); | |||||
nvgFill(vg); | |||||
} | |||||
void Port::onMouseDown(int button) { | void Port::onMouseDown(int button) { | ||||
if (button == 1) { | if (button == 1) { | ||||
disconnect(); | disconnect(); | ||||
@@ -3,37 +3,79 @@ | |||||
namespace rack { | namespace rack { | ||||
void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, float tension, NVGcolor color) { | |||||
float dist = pos1.minus(pos2).norm(); | |||||
Vec slump; | |||||
slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | |||||
Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, float tension, NVGcolor color, float opacity) { | |||||
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08); | |||||
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | |||||
// Wire | |||||
if (opacity > 0.0) { | |||||
nvgSave(vg); | |||||
nvgGlobalAlpha(vg, opacity); | |||||
float dist = pos1.minus(pos2).norm(); | |||||
Vec slump; | |||||
slump.y = (1.0 - tension) * (150.0 + 1.0*dist); | |||||
Vec pos3 = pos1.plus(pos2).div(2).plus(slump); | |||||
nvgLineJoin(vg, NVG_ROUND); | |||||
// Shadow | |||||
Vec pos4 = pos3.plus(slump.mult(0.08)); | |||||
nvgBeginPath(vg); | |||||
nvgMoveTo(vg, pos1.x, pos1.y); | |||||
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); | |||||
nvgStrokeColor(vg, colorShadow); | |||||
nvgStrokeWidth(vg, 5); | |||||
nvgStroke(vg); | |||||
// Wire outline | |||||
nvgBeginPath(vg); | |||||
nvgMoveTo(vg, pos1.x, pos1.y); | |||||
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); | |||||
nvgStrokeColor(vg, colorOutline); | |||||
nvgStrokeWidth(vg, 6); | |||||
nvgStroke(vg); | |||||
// Wire solid | |||||
nvgStrokeColor(vg, color); | |||||
nvgStrokeWidth(vg, 4); | |||||
nvgStroke(vg); | |||||
nvgRestore(vg); | |||||
} | |||||
// First plug | |||||
nvgBeginPath(vg); | |||||
nvgCircle(vg, pos1.x, pos1.y, 21/2.0); | |||||
nvgFillColor(vg, colorOutline); | |||||
nvgFill(vg); | |||||
nvgLineJoin(vg, NVG_ROUND); | |||||
nvgBeginPath(vg); | |||||
nvgCircle(vg, pos1.x, pos1.y, 19/2.0); | |||||
nvgFillColor(vg, color); | |||||
nvgFill(vg); | |||||
// Shadow | |||||
Vec pos4 = pos3.plus(slump.mult(0.08)); | |||||
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgMoveTo(vg, pos1.x, pos1.y); | |||||
nvgQuadTo(vg, pos4.x, pos4.y, pos2.x, pos2.y); | |||||
nvgStrokeColor(vg, colorShadow); | |||||
nvgStrokeWidth(vg, 5); | |||||
nvgStroke(vg); | |||||
// Wire outline | |||||
NVGcolor colorOutline = nvgRGBf(0, 0, 0); | |||||
nvgCircle(vg, pos1.x, pos1.y, 11/2.0); | |||||
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0)); | |||||
nvgFill(vg); | |||||
// Second plug | |||||
nvgBeginPath(vg); | |||||
nvgCircle(vg, pos2.x, pos2.y, 21/2.0); | |||||
nvgFillColor(vg, colorOutline); | |||||
nvgFill(vg); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgMoveTo(vg, pos1.x, pos1.y); | |||||
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); | |||||
nvgStrokeColor(vg, colorOutline); | |||||
nvgStrokeWidth(vg, 4); | |||||
nvgStroke(vg); | |||||
// Wire solid | |||||
nvgStrokeColor(vg, color); | |||||
nvgStrokeWidth(vg, 2); | |||||
nvgStroke(vg); | |||||
nvgCircle(vg, pos2.x, pos2.y, 19/2.0); | |||||
nvgFillColor(vg, color); | |||||
nvgFill(vg); | |||||
nvgBeginPath(vg); | |||||
nvgCircle(vg, pos2.x, pos2.y, 11/2.0); | |||||
nvgFillColor(vg, nvgRGBf(0.0, 0.0, 0.0)); | |||||
nvgFill(vg); | |||||
} | } | ||||
@@ -87,35 +129,29 @@ void WireWidget::updateWire() { | |||||
void WireWidget::draw(NVGcontext *vg) { | void WireWidget::draw(NVGcontext *vg) { | ||||
Vec outputPos, inputPos; | Vec outputPos, inputPos; | ||||
Vec absolutePos = getAbsolutePos(); | Vec absolutePos = getAbsolutePos(); | ||||
float wireOpacity = gScene->toolbar->wireOpacitySlider->value / 100.0; | |||||
float opacity = gScene->toolbar->wireOpacitySlider->value / 100.0; | |||||
// Compute location of pos1 and pos2 | |||||
if (outputPort) { | if (outputPort) { | ||||
outputPos = Rect(outputPort->getAbsolutePos(), outputPort->box.size).getCenter(); | outputPos = Rect(outputPort->getAbsolutePos(), outputPort->box.size).getCenter(); | ||||
} | } | ||||
else { | else { | ||||
outputPos = gMousePos; | outputPos = gMousePos; | ||||
wireOpacity = 1.0; | |||||
opacity = 1.0; | |||||
} | } | ||||
if (inputPort) { | if (inputPort) { | ||||
inputPos = Rect(inputPort->getAbsolutePos(), inputPort->box.size).getCenter(); | inputPos = Rect(inputPort->getAbsolutePos(), inputPort->box.size).getCenter(); | ||||
} | } | ||||
else { | else { | ||||
inputPos = gMousePos; | inputPos = gMousePos; | ||||
wireOpacity = 1.0; | |||||
opacity = 1.0; | |||||
} | } | ||||
outputPos = outputPos.minus(absolutePos); | outputPos = outputPos.minus(absolutePos); | ||||
inputPos = inputPos.minus(absolutePos); | inputPos = inputPos.minus(absolutePos); | ||||
bndNodePort(vg, outputPos.x, outputPos.y, BND_DEFAULT, color); | |||||
bndNodePort(vg, inputPos.x, inputPos.y, BND_DEFAULT, color); | |||||
nvgSave(vg); | |||||
if (wireOpacity > 0.0) { | |||||
nvgGlobalAlpha(vg, wireOpacity); | |||||
float tension = gScene->toolbar->wireTensionSlider->value; | |||||
drawWire(vg, outputPos, inputPos, tension, color); | |||||
} | |||||
nvgRestore(vg); | |||||
float tension = gScene->toolbar->wireTensionSlider->value; | |||||
drawWire(vg, outputPos, inputPos, tension, color, opacity); | |||||
} | } | ||||