@@ -0,0 +1,25 @@ | |||||
#pragma once | |||||
#include "app/common.hpp" | |||||
#include "widgets/TransparentWidget.hpp" | |||||
#include "app/CableWidget.hpp" | |||||
#include "app/PortWidget.hpp" | |||||
namespace rack { | |||||
struct CableContainer : TransparentWidget { | |||||
CableWidget *activeCable = NULL; | |||||
/** Takes ownership of `w` and adds it as a child if it isn't already */ | |||||
void setActiveCable(CableWidget *w); | |||||
/** "Drops" the cable onto the port, making an engine connection if successful */ | |||||
void commitActiveCable(); | |||||
void removeTopCable(PortWidget *port); | |||||
void removeAllCables(PortWidget *port); | |||||
/** Returns the most recently added cable connected to the given Port, i.e. the top of the stack */ | |||||
CableWidget *getTopCable(PortWidget *port); | |||||
void draw(NVGcontext *vg) override; | |||||
}; | |||||
} // namespace rack |
@@ -2,24 +2,24 @@ | |||||
#include "app/common.hpp" | #include "app/common.hpp" | ||||
#include "widgets/OpaqueWidget.hpp" | #include "widgets/OpaqueWidget.hpp" | ||||
#include "app/PortWidget.hpp" | #include "app/PortWidget.hpp" | ||||
#include "engine/Wire.hpp" | |||||
#include "engine/Cable.hpp" | |||||
namespace rack { | namespace rack { | ||||
struct WireWidget : OpaqueWidget { | |||||
struct CableWidget : OpaqueWidget { | |||||
PortWidget *outputPort = NULL; | PortWidget *outputPort = NULL; | ||||
PortWidget *inputPort = NULL; | PortWidget *inputPort = NULL; | ||||
PortWidget *hoveredOutputPort = NULL; | PortWidget *hoveredOutputPort = NULL; | ||||
PortWidget *hoveredInputPort = NULL; | PortWidget *hoveredInputPort = NULL; | ||||
Wire *wire = NULL; | |||||
Cable *cable = NULL; | |||||
NVGcolor color; | NVGcolor color; | ||||
WireWidget(); | |||||
~WireWidget(); | |||||
/** Synchronizes the plugged state of the widget to the owned wire */ | |||||
void updateWire(); | |||||
CableWidget(); | |||||
~CableWidget(); | |||||
/** Synchronizes the plugged state of the widget to the owned cable */ | |||||
void updateCable(); | |||||
math::Vec getOutputPos(); | math::Vec getOutputPos(); | ||||
math::Vec getInputPos(); | math::Vec getInputPos(); | ||||
json_t *toJson(); | json_t *toJson(); |
@@ -2,7 +2,7 @@ | |||||
#include "app/common.hpp" | #include "app/common.hpp" | ||||
#include "widgets/OpaqueWidget.hpp" | #include "widgets/OpaqueWidget.hpp" | ||||
#include "widgets/FramebufferWidget.hpp" | #include "widgets/FramebufferWidget.hpp" | ||||
#include "app/WireContainer.hpp" | |||||
#include "app/CableContainer.hpp" | |||||
#include "app/ModuleWidget.hpp" | #include "app/ModuleWidget.hpp" | ||||
@@ -13,15 +13,15 @@ struct RackWidget : OpaqueWidget { | |||||
FramebufferWidget *rails; | FramebufferWidget *rails; | ||||
// Only put ModuleWidgets in here | // Only put ModuleWidgets in here | ||||
Widget *moduleContainer; | Widget *moduleContainer; | ||||
// Only put WireWidgets in here | |||||
WireContainer *wireContainer; | |||||
// Only put CableWidgets in here | |||||
CableContainer *cableContainer; | |||||
std::string lastPath; | std::string lastPath; | ||||
math::Vec lastMousePos; | math::Vec lastMousePos; | ||||
RackWidget(); | RackWidget(); | ||||
~RackWidget(); | ~RackWidget(); | ||||
/** Completely clear the rack's modules and wires */ | |||||
/** Completely clear the rack's modules and cables */ | |||||
void clear(); | void clear(); | ||||
/** Clears the rack and loads the template patch */ | /** Clears the rack and loads the template patch */ | ||||
void reset(); | void reset(); | ||||
@@ -31,7 +31,7 @@ struct RackWidget : OpaqueWidget { | |||||
void saveTemplate(); | void saveTemplate(); | ||||
/** If `lastPath` is defined, ask the user to reload it */ | /** If `lastPath` is defined, ask the user to reload it */ | ||||
void revert(); | void revert(); | ||||
/** Disconnects all wires */ | |||||
/** Disconnects all cables */ | |||||
void disconnect(); | void disconnect(); | ||||
void save(std::string filename); | void save(std::string filename); | ||||
void load(std::string filename); | void load(std::string filename); | ||||
@@ -8,8 +8,8 @@ namespace rack { | |||||
struct Toolbar : OpaqueWidget { | struct Toolbar : OpaqueWidget { | ||||
// TODO Move these to future Rack app state | // TODO Move these to future Rack app state | ||||
float wireOpacity = 0.5; | |||||
float wireTension = 0.5; | |||||
float cableOpacity = 0.5; | |||||
float cableTension = 0.5; | |||||
Toolbar(); | Toolbar(); | ||||
void draw(NVGcontext *vg) override; | void draw(NVGcontext *vg) override; | ||||
@@ -1,25 +0,0 @@ | |||||
#pragma once | |||||
#include "app/common.hpp" | |||||
#include "widgets/TransparentWidget.hpp" | |||||
#include "app/WireWidget.hpp" | |||||
#include "app/PortWidget.hpp" | |||||
namespace rack { | |||||
struct WireContainer : TransparentWidget { | |||||
WireWidget *activeWire = NULL; | |||||
/** Takes ownership of `w` and adds it as a child if it isn't already */ | |||||
void setActiveWire(WireWidget *w); | |||||
/** "Drops" the wire onto the port, making an engine connection if successful */ | |||||
void commitActiveWire(); | |||||
void removeTopWire(PortWidget *port); | |||||
void removeAllWires(PortWidget *port); | |||||
/** Returns the most recently added wire connected to the given Port, i.e. the top of the stack */ | |||||
WireWidget *getTopWire(PortWidget *port); | |||||
void draw(NVGcontext *vg) override; | |||||
}; | |||||
} // namespace rack |
@@ -6,7 +6,7 @@ | |||||
namespace rack { | namespace rack { | ||||
struct Wire { | |||||
struct Cable { | |||||
int id = 0; | int id = 0; | ||||
Module *outputModule = NULL; | Module *outputModule = NULL; | ||||
int outputId; | int outputId; |
@@ -1,7 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include "common.hpp" | #include "common.hpp" | ||||
#include "engine/Module.hpp" | #include "engine/Module.hpp" | ||||
#include "engine/Wire.hpp" | |||||
#include "engine/Cable.hpp" | |||||
#include <vector> | #include <vector> | ||||
@@ -9,11 +9,11 @@ namespace rack { | |||||
struct Engine { | struct Engine { | ||||
/** Plugins should not manipulate other modules or wires unless that is the entire purpose of the module. | |||||
Your plugin needs to have a clear purpose for manipulating other modules and wires and must be done with a good UX. | |||||
/** Plugins should not manipulate other modules or cables unless that is the entire purpose of the module. | |||||
Your plugin needs to have a clear purpose for manipulating other modules and cables and must be done with a good UX. | |||||
*/ | */ | ||||
std::vector<Module*> modules; | std::vector<Module*> modules; | ||||
std::vector<Wire*> wires; | |||||
std::vector<Cable*> cables; | |||||
bool paused = false; | bool paused = false; | ||||
struct Internal; | struct Internal; | ||||
@@ -31,8 +31,8 @@ struct Engine { | |||||
void resetModule(Module *module); | void resetModule(Module *module); | ||||
void randomizeModule(Module *module); | void randomizeModule(Module *module); | ||||
/** Does not transfer pointer ownership */ | /** Does not transfer pointer ownership */ | ||||
void addWire(Wire *wire); | |||||
void removeWire(Wire *wire); | |||||
void addCable(Cable *cable); | |||||
void removeCable(Cable *cable); | |||||
void setParam(Module *module, int paramId, float value); | void setParam(Module *module, int paramId, float value); | ||||
void setParamSmooth(Module *module, int paramId, float value); | void setParamSmooth(Module *module, int paramId, float value); | ||||
int getNextModuleId(); | int getNextModuleId(); | ||||
@@ -7,7 +7,7 @@ namespace rack { | |||||
struct Input : Port { | struct Input : Port { | ||||
/** Returns the value if a wire is plugged in, otherwise returns the given default value */ | |||||
/** Returns the value if a cable is plugged in, otherwise returns the given default value */ | |||||
float normalize(float normalVoltage, int index = 0) { | float normalize(float normalVoltage, int index = 0) { | ||||
return active ? getVoltage(index) : normalVoltage; | return active ? getVoltage(index) : normalVoltage; | ||||
} | } | ||||
@@ -20,7 +20,7 @@ struct Port { | |||||
}; | }; | ||||
/** Number of polyphonic channels */ | /** Number of polyphonic channels */ | ||||
int numChannels = 1; | int numChannels = 1; | ||||
/** Whether a wire is plugged in */ | |||||
/** Whether a cable is plugged in */ | |||||
bool active = false; | bool active = false; | ||||
Light plugLights[2]; | Light plugLights[2]; | ||||
@@ -38,14 +38,14 @@ struct ModuleRemove : ModuleAction { | |||||
math::Vec pos; | math::Vec pos; | ||||
json_t *moduleJ; | json_t *moduleJ; | ||||
struct WireInfo { | |||||
int wireId; | |||||
struct CableInfo { | |||||
int cableId; | |||||
int outputModuleId; | int outputModuleId; | ||||
int outputId; | int outputId; | ||||
int inputModuleId; | int inputModuleId; | ||||
int inputId; | int inputId; | ||||
}; | }; | ||||
std::vector<WireInfo> wireInfos; | |||||
std::vector<CableInfo> cableInfos; | |||||
~ModuleRemove(); | ~ModuleRemove(); | ||||
void undo() override; | void undo() override; | ||||
@@ -70,8 +70,8 @@ struct ParamChange : ModuleAction { | |||||
}; | }; | ||||
struct WireAdd : Action { | |||||
int wireId; | |||||
struct CableAdd : Action { | |||||
int cableId; | |||||
int outputModuleId; | int outputModuleId; | ||||
int outputId; | int outputId; | ||||
int inputModuleId; | int inputModuleId; | ||||
@@ -81,8 +81,8 @@ struct WireAdd : Action { | |||||
}; | }; | ||||
struct WireRemove : Action { | |||||
int wireId; | |||||
struct CableRemove : Action { | |||||
int cableId; | |||||
int outputModuleId; | int outputModuleId; | ||||
int outputId; | int outputId; | ||||
int inputModuleId; | int inputModuleId; | ||||
@@ -92,8 +92,8 @@ struct WireRemove : Action { | |||||
}; | }; | ||||
struct WireMove : Action { | |||||
int wireId; | |||||
struct CableMove : Action { | |||||
int cableId; | |||||
int oldOutputModuleId; | int oldOutputModuleId; | ||||
int oldOutputId; | int oldOutputId; | ||||
int oldInputModuleId; | int oldInputModuleId; | ||||
@@ -65,8 +65,8 @@ | |||||
#include "app/SVGSwitch.hpp" | #include "app/SVGSwitch.hpp" | ||||
#include "app/ToggleSwitch.hpp" | #include "app/ToggleSwitch.hpp" | ||||
#include "app/Toolbar.hpp" | #include "app/Toolbar.hpp" | ||||
#include "app/WireContainer.hpp" | |||||
#include "app/WireWidget.hpp" | |||||
#include "app/CableContainer.hpp" | |||||
#include "app/CableWidget.hpp" | |||||
#include "engine/Engine.hpp" | #include "engine/Engine.hpp" | ||||
#include "engine/Input.hpp" | #include "engine/Input.hpp" | ||||
@@ -74,7 +74,7 @@ | |||||
#include "engine/Module.hpp" | #include "engine/Module.hpp" | ||||
#include "engine/Output.hpp" | #include "engine/Output.hpp" | ||||
#include "engine/Param.hpp" | #include "engine/Param.hpp" | ||||
#include "engine/Wire.hpp" | |||||
#include "engine/Cable.hpp" | |||||
#include "plugin/Plugin.hpp" | #include "plugin/Plugin.hpp" | ||||
#include "plugin/Model.hpp" | #include "plugin/Model.hpp" | ||||
@@ -11,8 +11,8 @@ void load(std::string filename); | |||||
extern float zoom; | extern float zoom; | ||||
extern float wireOpacity; | |||||
extern float wireTension; | |||||
extern float cableOpacity; | |||||
extern float cableTension; | |||||
extern bool paramTooltip; | extern bool paramTooltip; | ||||
extern bool powerMeter; | extern bool powerMeter; | ||||
extern bool lockModules; | extern bool lockModules; | ||||
@@ -0,0 +1,108 @@ | |||||
#include "app/CableContainer.hpp" | |||||
namespace rack { | |||||
void CableContainer::setActiveCable(CableWidget *w) { | |||||
if (activeCable) { | |||||
removeChild(activeCable); | |||||
delete activeCable; | |||||
activeCable = NULL; | |||||
} | |||||
if (w) { | |||||
if (w->parent == NULL) | |||||
addChild(w); | |||||
activeCable = w; | |||||
} | |||||
} | |||||
void CableContainer::commitActiveCable() { | |||||
if (!activeCable) | |||||
return; | |||||
if (activeCable->hoveredOutputPort) { | |||||
activeCable->outputPort = activeCable->hoveredOutputPort; | |||||
activeCable->hoveredOutputPort = NULL; | |||||
} | |||||
if (activeCable->hoveredInputPort) { | |||||
activeCable->inputPort = activeCable->hoveredInputPort; | |||||
activeCable->hoveredInputPort = NULL; | |||||
} | |||||
activeCable->updateCable(); | |||||
// Did it successfully connect? | |||||
if (activeCable->cable) { | |||||
// Make it permanent | |||||
activeCable = NULL; | |||||
} | |||||
else { | |||||
// Remove it | |||||
setActiveCable(NULL); | |||||
} | |||||
} | |||||
void CableContainer::removeTopCable(PortWidget *port) { | |||||
CableWidget *cable = getTopCable(port); | |||||
if (cable) { | |||||
removeChild(cable); | |||||
delete cable; | |||||
} | |||||
} | |||||
void CableContainer::removeAllCables(PortWidget *port) { | |||||
// As a convenience, de-hover the active cable so we don't attach them once it is dropped. | |||||
if (activeCable) { | |||||
if (activeCable->hoveredInputPort == port) | |||||
activeCable->hoveredInputPort = NULL; | |||||
if (activeCable->hoveredOutputPort == port) | |||||
activeCable->hoveredOutputPort = NULL; | |||||
} | |||||
// Build a list of CableWidgets to delete | |||||
std::list<CableWidget*> cables; | |||||
for (Widget *child : children) { | |||||
CableWidget *cable = dynamic_cast<CableWidget*>(child); | |||||
assert(cable); | |||||
if (!cable || cable->inputPort == port || cable->outputPort == port) { | |||||
if (activeCable == cable) { | |||||
activeCable = NULL; | |||||
} | |||||
// We can't delete from this list while we're iterating it, so add it to the deletion list. | |||||
cables.push_back(cable); | |||||
} | |||||
} | |||||
// Once we're done building the list, actually delete them | |||||
for (CableWidget *cable : cables) { | |||||
removeChild(cable); | |||||
delete cable; | |||||
} | |||||
} | |||||
CableWidget *CableContainer::getTopCable(PortWidget *port) { | |||||
for (auto it = children.rbegin(); it != children.rend(); it++) { | |||||
CableWidget *cable = dynamic_cast<CableWidget*>(*it); | |||||
assert(cable); | |||||
// Ignore incomplete cables | |||||
if (!(cable->inputPort && cable->outputPort)) | |||||
continue; | |||||
if (cable->inputPort == port || cable->outputPort == port) | |||||
return cable; | |||||
} | |||||
return NULL; | |||||
} | |||||
void CableContainer::draw(NVGcontext *vg) { | |||||
Widget::draw(vg); | |||||
// Cable plugs | |||||
for (Widget *child : children) { | |||||
CableWidget *cable = dynamic_cast<CableWidget*>(child); | |||||
assert(cable); | |||||
cable->drawPlugs(vg); | |||||
} | |||||
} | |||||
} // namespace rack |
@@ -1,4 +1,4 @@ | |||||
#include "app/WireWidget.hpp" | |||||
#include "app/CableWidget.hpp" | |||||
#include "app/Scene.hpp" | #include "app/Scene.hpp" | ||||
#include "engine/Engine.hpp" | #include "engine/Engine.hpp" | ||||
#include "componentlibrary.hpp" | #include "componentlibrary.hpp" | ||||
@@ -31,11 +31,11 @@ static void drawPlug(NVGcontext *vg, math::Vec pos, NVGcolor color) { | |||||
nvgFill(vg); | nvgFill(vg); | ||||
} | } | ||||
static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float thickness, float tension, float opacity) { | |||||
static void drawCable(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor color, float thickness, float tension, float opacity) { | |||||
NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | ||||
NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | ||||
// Wire | |||||
// Cable | |||||
if (opacity > 0.0) { | if (opacity > 0.0) { | ||||
nvgSave(vg); | nvgSave(vg); | ||||
// This power scaling looks more linear than actual linear scaling | // This power scaling looks more linear than actual linear scaling | ||||
@@ -57,7 +57,7 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co | |||||
nvgStrokeWidth(vg, thickness); | nvgStrokeWidth(vg, thickness); | ||||
nvgStroke(vg); | nvgStroke(vg); | ||||
// Wire outline | |||||
// Cable outline | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgMoveTo(vg, pos1.x, pos1.y); | nvgMoveTo(vg, pos1.x, pos1.y); | ||||
nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); | nvgQuadTo(vg, pos3.x, pos3.y, pos2.x, pos2.y); | ||||
@@ -65,7 +65,7 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co | |||||
nvgStrokeWidth(vg, thickness); | nvgStrokeWidth(vg, thickness); | ||||
nvgStroke(vg); | nvgStroke(vg); | ||||
// Wire solid | |||||
// Cable solid | |||||
nvgStrokeColor(vg, color); | nvgStrokeColor(vg, color); | ||||
nvgStrokeWidth(vg, thickness - 2); | nvgStrokeWidth(vg, thickness - 2); | ||||
nvgStroke(vg); | nvgStroke(vg); | ||||
@@ -75,7 +75,7 @@ static void drawWire(NVGcontext *vg, math::Vec pos1, math::Vec pos2, NVGcolor co | |||||
} | } | ||||
static const NVGcolor wireColors[] = { | |||||
static const NVGcolor cableColors[] = { | |||||
nvgRGB(0xc9, 0xb7, 0x0e), // yellow | nvgRGB(0xc9, 0xb7, 0x0e), // yellow | ||||
nvgRGB(0xc9, 0x18, 0x47), // red | nvgRGB(0xc9, 0x18, 0x47), // red | ||||
nvgRGB(0x0c, 0x8e, 0x15), // green | nvgRGB(0x0c, 0x8e, 0x15), // green | ||||
@@ -85,45 +85,45 @@ static const NVGcolor wireColors[] = { | |||||
// nvgRGB(0x88, 0x88, 0x88), // light gray | // nvgRGB(0x88, 0x88, 0x88), // light gray | ||||
// nvgRGB(0xaa, 0xaa, 0xaa), // white | // nvgRGB(0xaa, 0xaa, 0xaa), // white | ||||
}; | }; | ||||
static int lastWireColorId = -1; | |||||
static int lastCableColorId = -1; | |||||
WireWidget::WireWidget() { | |||||
lastWireColorId = (lastWireColorId + 1) % LENGTHOF(wireColors); | |||||
color = wireColors[lastWireColorId]; | |||||
CableWidget::CableWidget() { | |||||
lastCableColorId = (lastCableColorId + 1) % LENGTHOF(cableColors); | |||||
color = cableColors[lastCableColorId]; | |||||
} | } | ||||
WireWidget::~WireWidget() { | |||||
CableWidget::~CableWidget() { | |||||
outputPort = NULL; | outputPort = NULL; | ||||
inputPort = NULL; | inputPort = NULL; | ||||
updateWire(); | |||||
updateCable(); | |||||
} | } | ||||
void WireWidget::updateWire() { | |||||
void CableWidget::updateCable() { | |||||
if (inputPort && outputPort) { | if (inputPort && outputPort) { | ||||
// Check correct types | // Check correct types | ||||
assert(inputPort->type == PortWidget::INPUT); | assert(inputPort->type == PortWidget::INPUT); | ||||
assert(outputPort->type == PortWidget::OUTPUT); | assert(outputPort->type == PortWidget::OUTPUT); | ||||
if (!wire) { | |||||
wire = new Wire; | |||||
wire->outputModule = outputPort->module; | |||||
wire->outputId = outputPort->portId; | |||||
wire->inputModule = inputPort->module; | |||||
wire->inputId = inputPort->portId; | |||||
app()->engine->addWire(wire); | |||||
if (!cable) { | |||||
cable = new Cable; | |||||
cable->outputModule = outputPort->module; | |||||
cable->outputId = outputPort->portId; | |||||
cable->inputModule = inputPort->module; | |||||
cable->inputId = inputPort->portId; | |||||
app()->engine->addCable(cable); | |||||
} | } | ||||
} | } | ||||
else { | else { | ||||
if (wire) { | |||||
app()->engine->removeWire(wire); | |||||
delete wire; | |||||
wire = NULL; | |||||
if (cable) { | |||||
app()->engine->removeCable(cable); | |||||
delete cable; | |||||
cable = NULL; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
math::Vec WireWidget::getOutputPos() { | |||||
math::Vec CableWidget::getOutputPos() { | |||||
if (outputPort) { | if (outputPort) { | ||||
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); | return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); | ||||
} | } | ||||
@@ -135,7 +135,7 @@ math::Vec WireWidget::getOutputPos() { | |||||
} | } | ||||
} | } | ||||
math::Vec WireWidget::getInputPos() { | |||||
math::Vec CableWidget::getInputPos() { | |||||
if (inputPort) { | if (inputPort) { | ||||
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); | return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); | ||||
} | } | ||||
@@ -147,30 +147,30 @@ math::Vec WireWidget::getInputPos() { | |||||
} | } | ||||
} | } | ||||
json_t *WireWidget::toJson() { | |||||
json_t *CableWidget::toJson() { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
std::string s = color::toHexString(color); | std::string s = color::toHexString(color); | ||||
json_object_set_new(rootJ, "color", json_string(s.c_str())); | json_object_set_new(rootJ, "color", json_string(s.c_str())); | ||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void WireWidget::fromJson(json_t *rootJ) { | |||||
void CableWidget::fromJson(json_t *rootJ) { | |||||
json_t *colorJ = json_object_get(rootJ, "color"); | json_t *colorJ = json_object_get(rootJ, "color"); | ||||
if (colorJ) { | if (colorJ) { | ||||
// v0.6.0 and earlier patches use JSON objects. Just ignore them if so and use the existing wire color. | |||||
// v0.6.0 and earlier patches use JSON objects. Just ignore them if so and use the existing cable color. | |||||
if (json_is_string(colorJ)) | if (json_is_string(colorJ)) | ||||
color = color::fromHexString(json_string_value(colorJ)); | color = color::fromHexString(json_string_value(colorJ)); | ||||
} | } | ||||
} | } | ||||
void WireWidget::draw(NVGcontext *vg) { | |||||
float opacity = settings::wireOpacity; | |||||
float tension = settings::wireTension; | |||||
void CableWidget::draw(NVGcontext *vg) { | |||||
float opacity = settings::cableOpacity; | |||||
float tension = settings::cableTension; | |||||
WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; | |||||
if (activeWire) { | |||||
// Draw as opaque if the wire is active | |||||
if (activeWire == this) | |||||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||||
if (activeCable) { | |||||
// Draw as opaque if the cable is active | |||||
if (activeCable == this) | |||||
opacity = 1.0; | opacity = 1.0; | ||||
} | } | ||||
else { | else { | ||||
@@ -180,8 +180,8 @@ void WireWidget::draw(NVGcontext *vg) { | |||||
} | } | ||||
float thickness = 5; | float thickness = 5; | ||||
if (wire && wire->outputModule) { | |||||
Output *output = &wire->outputModule->outputs[wire->outputId]; | |||||
if (cable && cable->outputModule) { | |||||
Output *output = &cable->outputModule->outputs[cable->outputId]; | |||||
if (output->numChannels != 1) { | if (output->numChannels != 1) { | ||||
thickness = 9; | thickness = 9; | ||||
} | } | ||||
@@ -189,11 +189,11 @@ void WireWidget::draw(NVGcontext *vg) { | |||||
math::Vec outputPos = getOutputPos(); | math::Vec outputPos = getOutputPos(); | ||||
math::Vec inputPos = getInputPos(); | math::Vec inputPos = getInputPos(); | ||||
drawWire(vg, outputPos, inputPos, color, thickness, tension, opacity); | |||||
drawCable(vg, outputPos, inputPos, color, thickness, tension, opacity); | |||||
} | } | ||||
void WireWidget::drawPlugs(NVGcontext *vg) { | |||||
// TODO Figure out a way to draw plugs first and wires last, and cut the plug portion of the wire off. | |||||
void CableWidget::drawPlugs(NVGcontext *vg) { | |||||
// TODO Figure out a way to draw plugs first and cables last, and cut the plug portion of the cable off. | |||||
math::Vec outputPos = getOutputPos(); | math::Vec outputPos = getOutputPos(); | ||||
math::Vec inputPos = getInputPos(); | math::Vec inputPos = getInputPos(); | ||||
drawPlug(vg, outputPos, color); | drawPlug(vg, outputPos, color); |
@@ -251,10 +251,10 @@ void ModuleWidget::toggleBypass() { | |||||
void ModuleWidget::disconnect() { | void ModuleWidget::disconnect() { | ||||
for (PortWidget *input : inputs) { | for (PortWidget *input : inputs) { | ||||
app()->scene->rackWidget->wireContainer->removeAllWires(input); | |||||
app()->scene->rackWidget->cableContainer->removeAllCables(input); | |||||
} | } | ||||
for (PortWidget *output : outputs) { | for (PortWidget *output : outputs) { | ||||
app()->scene->rackWidget->wireContainer->removeAllWires(output); | |||||
app()->scene->rackWidget->cableContainer->removeAllCables(output); | |||||
} | } | ||||
} | } | ||||
@@ -28,7 +28,7 @@ PortWidget::~PortWidget() { | |||||
// HACK | // HACK | ||||
// See ModuleWidget::~ModuleWidget for description | // See ModuleWidget::~ModuleWidget for description | ||||
if (module) | if (module) | ||||
app()->scene->rackWidget->wireContainer->removeAllWires(this); | |||||
app()->scene->rackWidget->cableContainer->removeAllCables(this); | |||||
} | } | ||||
void PortWidget::step() { | void PortWidget::step() { | ||||
@@ -48,20 +48,20 @@ void PortWidget::step() { | |||||
} | } | ||||
void PortWidget::draw(NVGcontext *vg) { | void PortWidget::draw(NVGcontext *vg) { | ||||
WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; | |||||
if (activeWire) { | |||||
// Dim the PortWidget if the active wire cannot plug into this PortWidget | |||||
if (type == INPUT ? activeWire->inputPort : activeWire->outputPort) | |||||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||||
if (activeCable) { | |||||
// Dim the PortWidget if the active cable cannot plug into this PortWidget | |||||
if (type == INPUT ? activeCable->inputPort : activeCable->outputPort) | |||||
nvgGlobalAlpha(vg, 0.5); | nvgGlobalAlpha(vg, 0.5); | ||||
} | } | ||||
} | } | ||||
void PortWidget::onButton(const event::Button &e) { | void PortWidget::onButton(const event::Button &e) { | ||||
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | ||||
app()->scene->rackWidget->wireContainer->removeTopWire(this); | |||||
app()->scene->rackWidget->cableContainer->removeTopCable(this); | |||||
// HACK | // HACK | ||||
// Update hovered*PortWidget of active wire if applicable | |||||
// Update hovered*PortWidget of active cable if applicable | |||||
// event::DragEnter eDragEnter; | // event::DragEnter eDragEnter; | ||||
// onDragEnter(eDragEnter); | // onDragEnter(eDragEnter); | ||||
} | } | ||||
@@ -69,29 +69,29 @@ void PortWidget::onButton(const event::Button &e) { | |||||
} | } | ||||
void PortWidget::onDragStart(const event::DragStart &e) { | void PortWidget::onDragStart(const event::DragStart &e) { | ||||
// Try to grab wire on top of stack | |||||
WireWidget *wire = NULL; | |||||
// Try to grab cable on top of stack | |||||
CableWidget *cable = NULL; | |||||
if (type == INPUT || !app()->window->isModPressed()) { | if (type == INPUT || !app()->window->isModPressed()) { | ||||
wire = app()->scene->rackWidget->wireContainer->getTopWire(this); | |||||
cable = app()->scene->rackWidget->cableContainer->getTopCable(this); | |||||
} | } | ||||
if (wire) { | |||||
// Disconnect existing wire | |||||
(type == INPUT ? wire->inputPort : wire->outputPort) = NULL; | |||||
wire->updateWire(); | |||||
if (cable) { | |||||
// Disconnect existing cable | |||||
(type == INPUT ? cable->inputPort : cable->outputPort) = NULL; | |||||
cable->updateCable(); | |||||
} | } | ||||
else { | else { | ||||
// Create a new wire | |||||
wire = new WireWidget; | |||||
(type == INPUT ? wire->inputPort : wire->outputPort) = this; | |||||
// Create a new cable | |||||
cable = new CableWidget; | |||||
(type == INPUT ? cable->inputPort : cable->outputPort) = this; | |||||
} | } | ||||
app()->scene->rackWidget->wireContainer->setActiveWire(wire); | |||||
app()->scene->rackWidget->cableContainer->setActiveCable(cable); | |||||
} | } | ||||
void PortWidget::onDragEnd(const event::DragEnd &e) { | void PortWidget::onDragEnd(const event::DragEnd &e) { | ||||
// FIXME | // FIXME | ||||
// If the source PortWidget is deleted, this will be called, removing the cable | // If the source PortWidget is deleted, this will be called, removing the cable | ||||
app()->scene->rackWidget->wireContainer->commitActiveWire(); | |||||
app()->scene->rackWidget->cableContainer->commitActiveCable(); | |||||
} | } | ||||
void PortWidget::onDragDrop(const event::DragDrop &e) { | void PortWidget::onDragDrop(const event::DragDrop &e) { | ||||
@@ -112,14 +112,14 @@ void PortWidget::onDragEnter(const event::DragEnter &e) { | |||||
// Reject ports if this is an input port and something is already plugged into it | // Reject ports if this is an input port and something is already plugged into it | ||||
if (type == INPUT) { | if (type == INPUT) { | ||||
WireWidget *topWire = app()->scene->rackWidget->wireContainer->getTopWire(this); | |||||
if (topWire) | |||||
CableWidget *topCable = app()->scene->rackWidget->cableContainer->getTopCable(this); | |||||
if (topCable) | |||||
return; | return; | ||||
} | } | ||||
WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; | |||||
if (activeWire) { | |||||
(type == INPUT ? activeWire->hoveredInputPort : activeWire->hoveredOutputPort) = this; | |||||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||||
if (activeCable) { | |||||
(type == INPUT ? activeCable->hoveredInputPort : activeCable->hoveredOutputPort) = this; | |||||
} | } | ||||
} | } | ||||
@@ -128,9 +128,9 @@ void PortWidget::onDragLeave(const event::DragLeave &e) { | |||||
if (!originPort) | if (!originPort) | ||||
return; | return; | ||||
WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; | |||||
if (activeWire) { | |||||
(type == INPUT ? activeWire->hoveredInputPort : activeWire->hoveredOutputPort) = NULL; | |||||
CableWidget *activeCable = app()->scene->rackWidget->cableContainer->activeCable; | |||||
if (activeCable) { | |||||
(type == INPUT ? activeCable->hoveredInputPort : activeCable->hoveredOutputPort) = NULL; | |||||
} | } | ||||
} | } | ||||
@@ -11,7 +11,7 @@ void RackScrollWidget::step() { | |||||
math::Vec pos = app()->window->mousePos; | math::Vec pos = app()->window->mousePos; | ||||
math::Rect viewport = getViewport(box.zeroPos()); | math::Rect viewport = getViewport(box.zeroPos()); | ||||
// Scroll rack if dragging cable near the edge of the screen | // Scroll rack if dragging cable near the edge of the screen | ||||
if (app()->scene->rackWidget->wireContainer->activeWire) { | |||||
if (app()->scene->rackWidget->cableContainer->activeCable) { | |||||
float margin = 20.0; | float margin = 20.0; | ||||
float speed = 15.0; | float speed = 15.0; | ||||
if (pos.x <= viewport.pos.x + margin) | if (pos.x <= viewport.pos.x + margin) | ||||
@@ -49,8 +49,8 @@ RackWidget::RackWidget() { | |||||
moduleContainer = new ModuleContainer; | moduleContainer = new ModuleContainer; | ||||
addChild(moduleContainer); | addChild(moduleContainer); | ||||
wireContainer = new WireContainer; | |||||
addChild(wireContainer); | |||||
cableContainer = new CableContainer; | |||||
addChild(cableContainer); | |||||
} | } | ||||
RackWidget::~RackWidget() { | RackWidget::~RackWidget() { | ||||
@@ -58,8 +58,8 @@ RackWidget::~RackWidget() { | |||||
} | } | ||||
void RackWidget::clear() { | void RackWidget::clear() { | ||||
wireContainer->activeWire = NULL; | |||||
wireContainer->clearChildren(); | |||||
cableContainer->activeCable = NULL; | |||||
cableContainer->clearChildren(); | |||||
// Remove ModuleWidgets | // Remove ModuleWidgets | ||||
std::list<Widget*> widgets = moduleContainer->children; | std::list<Widget*> widgets = moduleContainer->children; | ||||
for (Widget *w : widgets) { | for (Widget *w : widgets) { | ||||
@@ -218,7 +218,7 @@ void RackWidget::disconnect() { | |||||
if (!osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK_CANCEL, "Remove all patch cables?")) | if (!osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK_CANCEL, "Remove all patch cables?")) | ||||
return; | return; | ||||
wireContainer->removeAllWires(NULL); | |||||
cableContainer->removeAllCables(NULL); | |||||
} | } | ||||
json_t *RackWidget::toJson() { | json_t *RackWidget::toJson() { | ||||
@@ -248,35 +248,35 @@ json_t *RackWidget::toJson() { | |||||
} | } | ||||
json_object_set_new(rootJ, "modules", modulesJ); | json_object_set_new(rootJ, "modules", modulesJ); | ||||
// wires | |||||
json_t *wiresJ = json_array(); | |||||
for (Widget *w : wireContainer->children) { | |||||
WireWidget *wireWidget = dynamic_cast<WireWidget*>(w); | |||||
assert(wireWidget); | |||||
// cables | |||||
json_t *cablesJ = json_array(); | |||||
for (Widget *w : cableContainer->children) { | |||||
CableWidget *cableWidget = dynamic_cast<CableWidget*>(w); | |||||
assert(cableWidget); | |||||
PortWidget *outputPort = wireWidget->outputPort; | |||||
PortWidget *inputPort = wireWidget->inputPort; | |||||
// Only serialize WireWidgets connected on both ends | |||||
PortWidget *outputPort = cableWidget->outputPort; | |||||
PortWidget *inputPort = cableWidget->inputPort; | |||||
// Only serialize CableWidgets connected on both ends | |||||
if (!(outputPort && inputPort)) | if (!(outputPort && inputPort)) | ||||
continue; | continue; | ||||
Wire *wire = wireWidget->wire; | |||||
assert(wire); | |||||
// wire | |||||
json_t *wireJ = wireWidget->toJson(); | |||||
Cable *cable = cableWidget->cable; | |||||
assert(cable); | |||||
// cable | |||||
json_t *cableJ = cableWidget->toJson(); | |||||
assert(outputPort->module); | assert(outputPort->module); | ||||
assert(inputPort->module); | assert(inputPort->module); | ||||
json_object_set_new(wireJ, "id", json_integer(wire->id)); | |||||
json_object_set_new(wireJ, "outputModuleId", json_integer(outputPort->module->id)); | |||||
json_object_set_new(wireJ, "outputId", json_integer(outputPort->portId)); | |||||
json_object_set_new(wireJ, "inputModuleId", json_integer(inputPort->module->id)); | |||||
json_object_set_new(wireJ, "inputId", json_integer(inputPort->portId)); | |||||
json_object_set_new(cableJ, "id", json_integer(cable->id)); | |||||
json_object_set_new(cableJ, "outputModuleId", json_integer(outputPort->module->id)); | |||||
json_object_set_new(cableJ, "outputId", json_integer(outputPort->portId)); | |||||
json_object_set_new(cableJ, "inputModuleId", json_integer(inputPort->module->id)); | |||||
json_object_set_new(cableJ, "inputId", json_integer(inputPort->portId)); | |||||
json_array_append_new(wiresJ, wireJ); | |||||
json_array_append_new(cablesJ, cableJ); | |||||
} | } | ||||
json_object_set_new(rootJ, "wires", wiresJ); | |||||
json_object_set_new(rootJ, "cables", cablesJ); | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
@@ -358,16 +358,19 @@ void RackWidget::fromJson(json_t *rootJ) { | |||||
} | } | ||||
} | } | ||||
// wires | |||||
json_t *wiresJ = json_object_get(rootJ, "wires"); | |||||
assert(wiresJ); | |||||
size_t wireIndex; | |||||
json_t *wireJ; | |||||
json_array_foreach(wiresJ, wireIndex, wireJ) { | |||||
int outputModuleId = json_integer_value(json_object_get(wireJ, "outputModuleId")); | |||||
int outputId = json_integer_value(json_object_get(wireJ, "outputId")); | |||||
int inputModuleId = json_integer_value(json_object_get(wireJ, "inputModuleId")); | |||||
int inputId = json_integer_value(json_object_get(wireJ, "inputId")); | |||||
// cables | |||||
json_t *cablesJ = json_object_get(rootJ, "cables"); | |||||
// Before 1.0, cables were called wires | |||||
if (!cablesJ) | |||||
cablesJ = json_object_get(rootJ, "wires"); | |||||
assert(cablesJ); | |||||
size_t cableIndex; | |||||
json_t *cableJ; | |||||
json_array_foreach(cablesJ, cableIndex, cableJ) { | |||||
int outputModuleId = json_integer_value(json_object_get(cableJ, "outputModuleId")); | |||||
int outputId = json_integer_value(json_object_get(cableJ, "outputId")); | |||||
int inputModuleId = json_integer_value(json_object_get(cableJ, "inputModuleId")); | |||||
int inputId = json_integer_value(json_object_get(cableJ, "inputId")); | |||||
// Get module widgets | // Get module widgets | ||||
ModuleWidget *outputModuleWidget = moduleWidgets[outputModuleId]; | ModuleWidget *outputModuleWidget = moduleWidgets[outputModuleId]; | ||||
@@ -400,14 +403,14 @@ void RackWidget::fromJson(json_t *rootJ) { | |||||
if (!outputPort || !inputPort) | if (!outputPort || !inputPort) | ||||
continue; | continue; | ||||
// Create WireWidget | |||||
WireWidget *wireWidget = new WireWidget; | |||||
wireWidget->fromJson(wireJ); | |||||
wireWidget->outputPort = outputPort; | |||||
wireWidget->inputPort = inputPort; | |||||
wireWidget->updateWire(); | |||||
// Add wire to rack | |||||
wireContainer->addChild(wireWidget); | |||||
// Create CableWidget | |||||
CableWidget *cableWidget = new CableWidget; | |||||
cableWidget->fromJson(cableJ); | |||||
cableWidget->outputPort = outputPort; | |||||
cableWidget->inputPort = inputPort; | |||||
cableWidget->updateCable(); | |||||
// Add cable to rack | |||||
cableContainer->addChild(cableWidget); | |||||
} | } | ||||
// Display a message if we have something to say | // Display a message if we have something to say | ||||
@@ -481,7 +484,7 @@ void RackWidget::addModuleAtMouse(ModuleWidget *m) { | |||||
} | } | ||||
void RackWidget::removeModule(ModuleWidget *m) { | void RackWidget::removeModule(ModuleWidget *m) { | ||||
// Disconnect wires | |||||
// Disconnect cables | |||||
m->disconnect(); | m->disconnect(); | ||||
// Remove module from Engine | // Remove module from Engine | ||||
@@ -156,12 +156,12 @@ struct ZoomQuantity : Quantity { | |||||
}; | }; | ||||
struct WireOpacityQuantity : Quantity { | |||||
struct CableOpacityQuantity : Quantity { | |||||
void setValue(float value) override { | void setValue(float value) override { | ||||
settings::wireOpacity = math::clamp(value, getMinValue(), getMaxValue()); | |||||
settings::cableOpacity = math::clamp(value, getMinValue(), getMaxValue()); | |||||
} | } | ||||
float getValue() override { | float getValue() override { | ||||
return settings::wireOpacity; | |||||
return settings::cableOpacity; | |||||
} | } | ||||
float getDefaultValue() override {return 0.5;} | float getDefaultValue() override {return 0.5;} | ||||
float getDisplayValue() override {return getValue() * 100.0;} | float getDisplayValue() override {return getValue() * 100.0;} | ||||
@@ -173,12 +173,12 @@ struct WireOpacityQuantity : Quantity { | |||||
struct WireTensionQuantity : Quantity { | |||||
struct CableTensionQuantity : Quantity { | |||||
void setValue(float value) override { | void setValue(float value) override { | ||||
settings::wireTension = math::clamp(value, getMinValue(), getMaxValue()); | |||||
settings::cableTension = math::clamp(value, getMinValue(), getMaxValue()); | |||||
} | } | ||||
float getValue() override { | float getValue() override { | ||||
return settings::wireTension; | |||||
return settings::cableTension; | |||||
} | } | ||||
float getDefaultValue() override {return 0.5;} | float getDefaultValue() override {return 0.5;} | ||||
std::string getLabel() override {return "Cable tension";} | std::string getLabel() override {return "Cable tension";} | ||||
@@ -281,15 +281,15 @@ struct SettingsButton : MenuButton { | |||||
zoomSlider->quantity = new ZoomQuantity; | zoomSlider->quantity = new ZoomQuantity; | ||||
menu->addChild(zoomSlider); | menu->addChild(zoomSlider); | ||||
Slider *wireOpacitySlider = new Slider; | |||||
wireOpacitySlider->box.size.x = 200.0; | |||||
wireOpacitySlider->quantity = new WireOpacityQuantity; | |||||
menu->addChild(wireOpacitySlider); | |||||
Slider *cableOpacitySlider = new Slider; | |||||
cableOpacitySlider->box.size.x = 200.0; | |||||
cableOpacitySlider->quantity = new CableOpacityQuantity; | |||||
menu->addChild(cableOpacitySlider); | |||||
Slider *wireTensionSlider = new Slider; | |||||
wireTensionSlider->box.size.x = 200.0; | |||||
wireTensionSlider->quantity = new WireTensionQuantity; | |||||
menu->addChild(wireTensionSlider); | |||||
Slider *cableTensionSlider = new Slider; | |||||
cableTensionSlider->box.size.x = 200.0; | |||||
cableTensionSlider->quantity = new CableTensionQuantity; | |||||
menu->addChild(cableTensionSlider); | |||||
} | } | ||||
}; | }; | ||||
@@ -1,108 +0,0 @@ | |||||
#include "app/WireContainer.hpp" | |||||
namespace rack { | |||||
void WireContainer::setActiveWire(WireWidget *w) { | |||||
if (activeWire) { | |||||
removeChild(activeWire); | |||||
delete activeWire; | |||||
activeWire = NULL; | |||||
} | |||||
if (w) { | |||||
if (w->parent == NULL) | |||||
addChild(w); | |||||
activeWire = w; | |||||
} | |||||
} | |||||
void WireContainer::commitActiveWire() { | |||||
if (!activeWire) | |||||
return; | |||||
if (activeWire->hoveredOutputPort) { | |||||
activeWire->outputPort = activeWire->hoveredOutputPort; | |||||
activeWire->hoveredOutputPort = NULL; | |||||
} | |||||
if (activeWire->hoveredInputPort) { | |||||
activeWire->inputPort = activeWire->hoveredInputPort; | |||||
activeWire->hoveredInputPort = NULL; | |||||
} | |||||
activeWire->updateWire(); | |||||
// Did it successfully connect? | |||||
if (activeWire->wire) { | |||||
// Make it permanent | |||||
activeWire = NULL; | |||||
} | |||||
else { | |||||
// Remove it | |||||
setActiveWire(NULL); | |||||
} | |||||
} | |||||
void WireContainer::removeTopWire(PortWidget *port) { | |||||
WireWidget *wire = getTopWire(port); | |||||
if (wire) { | |||||
removeChild(wire); | |||||
delete wire; | |||||
} | |||||
} | |||||
void WireContainer::removeAllWires(PortWidget *port) { | |||||
// As a convenience, de-hover the active wire so we don't attach them once it is dropped. | |||||
if (activeWire) { | |||||
if (activeWire->hoveredInputPort == port) | |||||
activeWire->hoveredInputPort = NULL; | |||||
if (activeWire->hoveredOutputPort == port) | |||||
activeWire->hoveredOutputPort = NULL; | |||||
} | |||||
// Build a list of WireWidgets to delete | |||||
std::list<WireWidget*> wires; | |||||
for (Widget *child : children) { | |||||
WireWidget *wire = dynamic_cast<WireWidget*>(child); | |||||
assert(wire); | |||||
if (!wire || wire->inputPort == port || wire->outputPort == port) { | |||||
if (activeWire == wire) { | |||||
activeWire = NULL; | |||||
} | |||||
// We can't delete from this list while we're iterating it, so add it to the deletion list. | |||||
wires.push_back(wire); | |||||
} | |||||
} | |||||
// Once we're done building the list, actually delete them | |||||
for (WireWidget *wire : wires) { | |||||
removeChild(wire); | |||||
delete wire; | |||||
} | |||||
} | |||||
WireWidget *WireContainer::getTopWire(PortWidget *port) { | |||||
for (auto it = children.rbegin(); it != children.rend(); it++) { | |||||
WireWidget *wire = dynamic_cast<WireWidget*>(*it); | |||||
assert(wire); | |||||
// Ignore incomplete wires | |||||
if (!(wire->inputPort && wire->outputPort)) | |||||
continue; | |||||
if (wire->inputPort == port || wire->outputPort == port) | |||||
return wire; | |||||
} | |||||
return NULL; | |||||
} | |||||
void WireContainer::draw(NVGcontext *vg) { | |||||
Widget::draw(vg); | |||||
// Wire plugs | |||||
for (Widget *child : children) { | |||||
WireWidget *wire = dynamic_cast<WireWidget*>(child); | |||||
assert(wire); | |||||
wire->drawPlugs(vg); | |||||
} | |||||
} | |||||
} // namespace rack |
@@ -1,10 +1,10 @@ | |||||
#include "engine/Wire.hpp" | |||||
#include "engine/Cable.hpp" | |||||
namespace rack { | namespace rack { | ||||
void Wire::step() { | |||||
void Cable::step() { | |||||
Output *output = &outputModule->outputs[outputId]; | Output *output = &outputModule->outputs[outputId]; | ||||
Input *input = &inputModule->inputs[inputId]; | Input *input = &inputModule->inputs[inputId]; | ||||
// Match number of polyphonic channels to output port | // Match number of polyphonic channels to output port |
@@ -53,7 +53,7 @@ struct Engine::Internal { | |||||
Module *resetModule = NULL; | Module *resetModule = NULL; | ||||
Module *randomizeModule = NULL; | Module *randomizeModule = NULL; | ||||
int nextModuleId = 1; | int nextModuleId = 1; | ||||
int nextWireId = 1; | |||||
int nextCableId = 1; | |||||
// Parameter smoothing | // Parameter smoothing | ||||
Module *smoothModule = NULL; | Module *smoothModule = NULL; | ||||
@@ -76,8 +76,8 @@ Engine::Engine() { | |||||
} | } | ||||
Engine::~Engine() { | Engine::~Engine() { | ||||
// Make sure there are no wires or modules in the rack on destruction. This suggests that a module failed to remove itself before the RackWidget was destroyed. | |||||
assert(wires.empty()); | |||||
// Make sure there are no cables or modules in the rack on destruction. This suggests that a module failed to remove itself before the RackWidget was destroyed. | |||||
assert(cables.empty()); | |||||
assert(modules.empty()); | assert(modules.empty()); | ||||
delete internal; | delete internal; | ||||
@@ -172,8 +172,8 @@ static void Engine_step(Engine *engine) { | |||||
} | } | ||||
// Step cables | // Step cables | ||||
for (Wire *wire : engine->wires) { | |||||
wire->step(); | |||||
for (Cable *cable : engine->cables) { | |||||
cable->step(); | |||||
} | } | ||||
} | } | ||||
@@ -257,10 +257,10 @@ void Engine::removeModule(Module *module) { | |||||
if (module == internal->smoothModule) { | if (module == internal->smoothModule) { | ||||
internal->smoothModule = NULL; | internal->smoothModule = NULL; | ||||
} | } | ||||
// Check that all wires are disconnected | |||||
for (Wire *wire : wires) { | |||||
assert(wire->outputModule != module); | |||||
assert(wire->inputModule != module); | |||||
// Check that all cables are disconnected | |||||
for (Cable *cable : cables) { | |||||
assert(cable->outputModule != module); | |||||
assert(cable->inputModule != module); | |||||
} | } | ||||
// Check that the module actually exists | // Check that the module actually exists | ||||
auto it = std::find(modules.begin(), modules.end(), module); | auto it = std::find(modules.begin(), modules.end(), module); | ||||
@@ -290,55 +290,55 @@ static void Engine_updateActive(Engine *engine) { | |||||
} | } | ||||
} | } | ||||
// Set inputs/outputs to active | // Set inputs/outputs to active | ||||
for (Wire *wire : engine->wires) { | |||||
wire->outputModule->outputs[wire->outputId].active = true; | |||||
wire->inputModule->inputs[wire->inputId].active = true; | |||||
for (Cable *cable : engine->cables) { | |||||
cable->outputModule->outputs[cable->outputId].active = true; | |||||
cable->inputModule->inputs[cable->inputId].active = true; | |||||
} | } | ||||
} | } | ||||
void Engine::addWire(Wire *wire) { | |||||
assert(wire); | |||||
void Engine::addCable(Cable *cable) { | |||||
assert(cable); | |||||
VIPLock vipLock(internal->vipMutex); | VIPLock vipLock(internal->vipMutex); | ||||
std::lock_guard<std::mutex> lock(internal->mutex); | std::lock_guard<std::mutex> lock(internal->mutex); | ||||
// Check wire properties | |||||
assert(wire->outputModule); | |||||
assert(wire->inputModule); | |||||
// Check that the wire is not already added, and that the input is not already used by another cable | |||||
for (Wire *wire2 : wires) { | |||||
assert(wire2 != wire); | |||||
assert(!(wire2->inputModule == wire->inputModule && wire2->inputId == wire->inputId)); | |||||
// Check cable properties | |||||
assert(cable->outputModule); | |||||
assert(cable->inputModule); | |||||
// Check that the cable is not already added, and that the input is not already used by another cable | |||||
for (Cable *cable2 : cables) { | |||||
assert(cable2 != cable); | |||||
assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId)); | |||||
} | } | ||||
// Set ID | // Set ID | ||||
if (wire->id == 0) { | |||||
if (cable->id == 0) { | |||||
// Automatically assign ID | // Automatically assign ID | ||||
wire->id = internal->nextWireId++; | |||||
cable->id = internal->nextCableId++; | |||||
} | } | ||||
else { | else { | ||||
// Manual ID | // Manual ID | ||||
// Check that the ID is not already taken | // Check that the ID is not already taken | ||||
for (Wire *w : wires) { | |||||
assert(wire->id != w->id); | |||||
for (Cable *w : cables) { | |||||
assert(cable->id != w->id); | |||||
} | } | ||||
} | } | ||||
// Add the wire | |||||
wires.push_back(wire); | |||||
// Add the cable | |||||
cables.push_back(cable); | |||||
Engine_updateActive(this); | Engine_updateActive(this); | ||||
} | } | ||||
void Engine::removeWire(Wire *wire) { | |||||
assert(wire); | |||||
void Engine::removeCable(Cable *cable) { | |||||
assert(cable); | |||||
VIPLock vipLock(internal->vipMutex); | VIPLock vipLock(internal->vipMutex); | ||||
std::lock_guard<std::mutex> lock(internal->mutex); | std::lock_guard<std::mutex> lock(internal->mutex); | ||||
// Check that the wire is already added | |||||
auto it = std::find(wires.begin(), wires.end(), wire); | |||||
assert(it != wires.end()); | |||||
// Check that the cable is already added | |||||
auto it = std::find(cables.begin(), cables.end(), cable); | |||||
assert(it != cables.end()); | |||||
// Set input to 0V | // Set input to 0V | ||||
wire->inputModule->inputs[wire->inputId].value = 0.f; | |||||
// Remove the wire | |||||
wires.erase(it); | |||||
cable->inputModule->inputs[cable->inputId].value = 0.f; | |||||
// Remove the cable | |||||
cables.erase(it); | |||||
Engine_updateActive(this); | Engine_updateActive(this); | ||||
// Remove ID | // Remove ID | ||||
wire->id = 0; | |||||
cable->id = 0; | |||||
} | } | ||||
void Engine::setParam(Module *module, int paramId, float value) { | void Engine::setParam(Module *module, int paramId, float value) { | ||||
@@ -37,9 +37,9 @@ void ModuleRemove::undo() { | |||||
moduleWidget->fromJson(moduleJ); | moduleWidget->fromJson(moduleJ); | ||||
app()->scene->rackWidget->addModule(moduleWidget); | app()->scene->rackWidget->addModule(moduleWidget); | ||||
// Add wires | |||||
for (WireInfo &wireInfo : wireInfos) { | |||||
// TODO Add wire | |||||
// Add cables | |||||
for (CableInfo &cableInfo : cableInfos) { | |||||
// TODO Add cable | |||||
} | } | ||||
} | } | ||||
@@ -32,13 +32,13 @@ static json_t *settingsToJson() { | |||||
json_object_set_new(rootJ, "windowPos", windowPosJ); | json_object_set_new(rootJ, "windowPos", windowPosJ); | ||||
} | } | ||||
// wireOpacity | |||||
json_t *wireOpacityJ = json_real(wireOpacity); | |||||
json_object_set_new(rootJ, "wireOpacity", wireOpacityJ); | |||||
// cableOpacity | |||||
json_t *cableOpacityJ = json_real(cableOpacity); | |||||
json_object_set_new(rootJ, "cableOpacity", cableOpacityJ); | |||||
// wireTension | |||||
json_t *wireTensionJ = json_real(wireTension); | |||||
json_object_set_new(rootJ, "wireTension", wireTensionJ); | |||||
// cableTension | |||||
json_t *cableTensionJ = json_real(cableTension); | |||||
json_object_set_new(rootJ, "cableTension", cableTensionJ); | |||||
// zoom | // zoom | ||||
json_t *zoomJ = json_real(zoom); | json_t *zoomJ = json_real(zoom); | ||||
@@ -98,15 +98,15 @@ static void settingsFromJson(json_t *rootJ) { | |||||
app()->window->setWindowPos(math::Vec(x, y)); | app()->window->setWindowPos(math::Vec(x, y)); | ||||
} | } | ||||
// wireOpacity | |||||
json_t *wireOpacityJ = json_object_get(rootJ, "wireOpacity"); | |||||
if (wireOpacityJ) | |||||
wireOpacity = json_number_value(wireOpacityJ); | |||||
// cableOpacity | |||||
json_t *cableOpacityJ = json_object_get(rootJ, "cableOpacity"); | |||||
if (cableOpacityJ) | |||||
cableOpacity = json_number_value(cableOpacityJ); | |||||
// tension | // tension | ||||
json_t *tensionJ = json_object_get(rootJ, "wireTension"); | |||||
json_t *tensionJ = json_object_get(rootJ, "cableTension"); | |||||
if (tensionJ) | if (tensionJ) | ||||
wireTension = json_number_value(tensionJ); | |||||
cableTension = json_number_value(tensionJ); | |||||
// zoom | // zoom | ||||
json_t *zoomJ = json_object_get(rootJ, "zoom"); | json_t *zoomJ = json_object_get(rootJ, "zoom"); | ||||
@@ -192,8 +192,8 @@ void load(std::string filename) { | |||||
float zoom = 1.0; | float zoom = 1.0; | ||||
float wireOpacity = 0.5; | |||||
float wireTension = 0.5; | |||||
float cableOpacity = 0.5; | |||||
float cableTension = 0.5; | |||||
bool paramTooltip = false; | bool paramTooltip = false; | ||||
bool powerMeter = false; | bool powerMeter = false; | ||||
bool lockModules = false; | bool lockModules = false; | ||||