| @@ -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; | ||||