Browse Source

Allow multiple cables on input Port.

tags/v2.5.0
Andrew Belt 7 months ago
parent
commit
129eb3ca4b
3 changed files with 44 additions and 54 deletions
  1. +1
    -0
      include/app/RackWidget.hpp
  2. +33
    -54
      src/app/PortWidget.cpp
  3. +10
    -0
      src/app/RackWidget.cpp

+ 1
- 0
include/app/RackWidget.hpp View File

@@ -127,6 +127,7 @@ struct RackWidget : widget::OpaqueWidget {
/** Returns the most recently added complete cable connected to the given Port, i.e. the top of the stack. */ /** Returns the most recently added complete cable connected to the given Port, i.e. the top of the stack. */
CableWidget* getTopCable(PortWidget* port); CableWidget* getTopCable(PortWidget* port);
CableWidget* getCable(int64_t cableId); CableWidget* getCable(int64_t cableId);
CableWidget* getCable(PortWidget* outputPort, PortWidget* inputPort);
std::vector<CableWidget*> getCompleteCables(); std::vector<CableWidget*> getCompleteCables();
/** Returns all cables attached to port, complete or not. */ /** Returns all cables attached to port, complete or not. */
std::vector<CableWidget*> getCablesOnPort(PortWidget* port); std::vector<CableWidget*> getCablesOnPort(PortWidget* port);


+ 33
- 54
src/app/PortWidget.cpp View File

@@ -250,7 +250,7 @@ void PortWidget::createContextMenu() {
!topCw !topCw
)); ));


if (type == engine::Port::INPUT) {
{
PortCloneCableItem* item = createMenuItem<PortCloneCableItem>("Duplicate top cable", RACK_MOD_CTRL_NAME "+drag"); PortCloneCableItem* item = createMenuItem<PortCloneCableItem>("Duplicate top cable", RACK_MOD_CTRL_NAME "+drag");
item->disabled = !topCw; item->disabled = !topCw;
item->pw = this; item->pw = this;
@@ -261,11 +261,9 @@ void PortWidget::createContextMenu() {
menu->addChild(new ui::MenuSeparator); menu->addChild(new ui::MenuSeparator);


// New cable items // New cable items
bool createCableDisabled = (type == engine::Port::INPUT) && topCw;
for (NVGcolor color : settings::cableColors) { for (NVGcolor color : settings::cableColors) {
// Include extra leading spaces for the color circle // Include extra leading spaces for the color circle
PortCreateCableItem* item = createMenuItem<PortCreateCableItem>("New cable", "Click+drag"); PortCreateCableItem* item = createMenuItem<PortCreateCableItem>("New cable", "Click+drag");
item->disabled = createCableDisabled;
item->pw = this; item->pw = this;
item->color = color; item->color = color;
menu->addChild(item); menu->addChild(item);
@@ -366,35 +364,31 @@ void PortWidget::onDragStart(const DragStartEvent& e) {
}); });


CableWidget* cw = NULL; CableWidget* cw = NULL;
if (internal->overrideCreateCable) {
int mods = APP->window->getMods();
if (internal->overrideCreateCable || (mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
// Create cable with Ctrl+drag or PortCreateCableItem
// Keep cable NULL. Will be created below // Keep cable NULL. Will be created below
} }
else if (internal->overrideCloneCw || (APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL) {
if (type == engine::Port::OUTPUT) {
// Ctrl-clicking an output creates a new cable.
// Keep cable NULL. Will be created below
}
else {
// Ctrl-clicking an input clones the cable already patched to it.
CableWidget* cloneCw;
if (internal->overrideCloneCw)
cloneCw = internal->overrideCloneCw;
else if (internal->overrideCloneCw || (mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
// Clone top cable with Ctrl+shift+drag or PortCloneCableItem
CableWidget* cloneCw = internal->overrideCloneCw;
if (!cloneCw)
cloneCw = APP->scene->rack->getTopCable(this);

if (cloneCw) {
cw = new CableWidget;
cw->color = cloneCw->color;
if (type == engine::Port::OUTPUT)
cw->inputPort = cloneCw->inputPort;
else else
cloneCw = APP->scene->rack->getTopCable(this);

if (cloneCw) {
cw = new CableWidget;
cw->color = cloneCw->color;
cw->outputPort = cloneCw->outputPort; cw->outputPort = cloneCw->outputPort;
cw->updateCable();
}
cw->updateCable();
} }
} }
else { else {
// Grab cable on top of stack // Grab cable on top of stack
if (internal->overrideCw)
cw = internal->overrideCw;
else
cw = internal->overrideCw;
if (!cw)
cw = APP->scene->rack->getTopCable(this); cw = APP->scene->rack->getTopCable(this);


if (cw) { if (cw) {
@@ -414,13 +408,6 @@ void PortWidget::onDragStart(const DragStartEvent& e) {
} }


if (!cw) { if (!cw) {
// Check that inputs don't already have a cable
if (type == engine::Port::INPUT) {
CableWidget* topCw = APP->scene->rack->getTopCable(this);
if (topCw)
return;
}

// Create a new cable // Create a new cable
cw = new CableWidget; cw = new CableWidget;


@@ -465,52 +452,44 @@ void PortWidget::onDragEnd(const DragEndEvent& e) {




void PortWidget::onDragDrop(const DragDropEvent& e) { void PortWidget::onDragDrop(const DragDropEvent& e) {
// HACK: Only delete tooltip if we're not (normal) dragging it.
if (e.origin == this)
createTooltip();

if (e.button != GLFW_MOUSE_BUTTON_LEFT) if (e.button != GLFW_MOUSE_BUTTON_LEFT)
return; return;


// Reject ports if this is an input port and something is already plugged into it
if (type == engine::Port::INPUT) {
if (APP->scene->rack->getTopCable(this))
return;
}
// HACK: Only delete tooltip if we're not (normal) dragging it.
if (e.origin == this)
createTooltip();


CableWidget* cw = APP->scene->rack->getIncompleteCable(); CableWidget* cw = APP->scene->rack->getIncompleteCable();
if (cw) { if (cw) {
cw->hoveredOutputPort = cw->hoveredInputPort = NULL; cw->hoveredOutputPort = cw->hoveredInputPort = NULL;
if (type == engine::Port::OUTPUT)
if (type == engine::Port::OUTPUT && cw->inputPort && !APP->scene->rack->getCable(this, cw->inputPort)) {
cw->outputPort = this; cw->outputPort = this;
else
}
if (type == engine::Port::INPUT && cw->outputPort && !APP->scene->rack->getCable(cw->outputPort, this)) {
cw->inputPort = this; cw->inputPort = this;
}
cw->updateCable(); cw->updateCable();
} }
} }




void PortWidget::onDragEnter(const DragEnterEvent& e) { void PortWidget::onDragEnter(const DragEnterEvent& e) {
PortWidget* pw = dynamic_cast<PortWidget*>(e.origin);
if (pw) {
createTooltip();
}

if (e.button != GLFW_MOUSE_BUTTON_LEFT) if (e.button != GLFW_MOUSE_BUTTON_LEFT)
return; return;


// Reject ports if this is an input port and something is already plugged into it
if (type == engine::Port::INPUT) {
if (APP->scene->rack->getTopCable(this))
return;
PortWidget* pw = dynamic_cast<PortWidget*>(e.origin);
if (pw) {
createTooltip();
} }


CableWidget* cw = APP->scene->rack->getIncompleteCable(); CableWidget* cw = APP->scene->rack->getIncompleteCable();
if (cw) { if (cw) {
if (type == engine::Port::OUTPUT)
if (type == engine::Port::OUTPUT && cw->inputPort && !APP->scene->rack->getCable(this, cw->inputPort)) {
cw->hoveredOutputPort = this; cw->hoveredOutputPort = this;
else
}
if (type == engine::Port::INPUT && cw->outputPort && !APP->scene->rack->getCable(cw->outputPort, this)) {
cw->hoveredInputPort = this; cw->hoveredInputPort = this;
}
} }
} }


@@ -529,7 +508,7 @@ void PortWidget::onDragLeave(const DragLeaveEvent& e) {
if (cw) { if (cw) {
if (type == engine::Port::OUTPUT) if (type == engine::Port::OUTPUT)
cw->hoveredOutputPort = NULL; cw->hoveredOutputPort = NULL;
else
if (type == engine::Port::INPUT)
cw->hoveredInputPort = NULL; cw->hoveredInputPort = NULL;
} }
} }


+ 10
- 0
src/app/RackWidget.cpp View File

@@ -1467,6 +1467,16 @@ CableWidget* RackWidget::getCable(int64_t cableId) {
return NULL; return NULL;
} }


CableWidget* RackWidget::getCable(PortWidget* outputPort, PortWidget* inputPort) {
for (widget::Widget* w : internal->cableContainer->children) {
CableWidget* cw = dynamic_cast<CableWidget*>(w);
assert(cw);
if (cw->outputPort == outputPort && cw->inputPort == inputPort)
return cw;
}
return NULL;
}

std::vector<CableWidget*> RackWidget::getCompleteCables() { std::vector<CableWidget*> RackWidget::getCompleteCables() {
std::vector<CableWidget*> cws; std::vector<CableWidget*> cws;
cws.reserve(internal->cableContainer->children.size()); cws.reserve(internal->cableContainer->children.size());


Loading…
Cancel
Save