#include "app/PortWidget.hpp" #include "app/Scene.hpp" #include "window.hpp" #include "app.hpp" #include "history.hpp" #include "componentlibrary.hpp" namespace rack { struct PlugLight : MultiLightWidget { PlugLight() { addBaseColor(color::GREEN); addBaseColor(color::RED); box.size = math::Vec(8, 8); bgColor = color::BLACK_TRANSPARENT; } }; PortWidget::PortWidget() { plugLight = new PlugLight; } PortWidget::~PortWidget() { // plugLight is not a child and is thus owned by the PortWidget, so we need to delete it here delete plugLight; // HACK if (module) app()->scene->rackWidget->cableContainer->clearPort(this); } void PortWidget::step() { if (!module) return; std::vector values(2); if (type == OUTPUT) { values[0] = module->outputs[portId].plugLights[0].getBrightness(); values[1] = module->outputs[portId].plugLights[1].getBrightness(); } else { values[0] = module->inputs[portId].plugLights[0].getBrightness(); values[1] = module->inputs[portId].plugLights[1].getBrightness(); } plugLight->setValues(values); } void PortWidget::draw(NVGcontext *vg) { CableWidget *cw = app()->scene->rackWidget->cableContainer->incompleteCable; if (cw) { // Dim the PortWidget if the active cable cannot plug into this PortWidget if (type == OUTPUT ? cw->outputPort : cw->inputPort) nvgGlobalAlpha(vg, 0.5); } Widget::draw(vg); } void PortWidget::onButton(const event::Button &e) { if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { CableWidget *cw = app()->scene->rackWidget->cableContainer->getTopCable(this); if (cw) { // history::CableRemove history::CableRemove *h = new history::CableRemove; h->setCable(cw); app()->history->push(h); app()->scene->rackWidget->cableContainer->removeCable(cw); delete cw; } } e.consume(this); } void PortWidget::onDragStart(const event::DragStart &e) { CableWidget *cw = NULL; if (type == OUTPUT && (app()->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { // Keep cable NULL } else { // Grab cable on top of stack cw = app()->scene->rackWidget->cableContainer->getTopCable(this); } if (cw) { // history::CableRemove history::CableRemove *h = new history::CableRemove; h->setCable(cw); app()->history->push(h); // Disconnect and reuse existing cable app()->scene->rackWidget->cableContainer->removeCable(cw); if (type == OUTPUT) cw->setOutput(NULL); else cw->setInput(NULL); } else { // Create a new cable cw = new CableWidget; if (type == OUTPUT) cw->setOutput(this); else cw->setInput(this); } app()->scene->rackWidget->cableContainer->setIncompleteCable(cw); } void PortWidget::onDragEnd(const event::DragEnd &e) { // FIXME // If the source PortWidget is deleted, this will be called, removing the cable CableWidget *cw = app()->scene->rackWidget->cableContainer->releaseIncompleteCable(); if (cw->isComplete()) { app()->scene->rackWidget->cableContainer->addCable(cw); // history::CableAdd history::CableAdd *h = new history::CableAdd; h->setCable(cw); app()->history->push(h); } else { delete cw; } } void PortWidget::onDragDrop(const event::DragDrop &e) { // Reject ports if this is an input port and something is already plugged into it if (type == INPUT) { if (app()->scene->rackWidget->cableContainer->getTopCable(this)) return; } CableWidget *cw = app()->scene->rackWidget->cableContainer->incompleteCable; if (cw) { cw->hoveredOutputPort = cw->hoveredInputPort = NULL; if (type == OUTPUT) cw->setOutput(this); else cw->setInput(this); } } void PortWidget::onDragEnter(const event::DragEnter &e) { // Reject ports if this is an input port and something is already plugged into it if (type == INPUT) { if (app()->scene->rackWidget->cableContainer->getTopCable(this)) return; } CableWidget *cw = app()->scene->rackWidget->cableContainer->incompleteCable; if (cw) { if (type == OUTPUT) cw->hoveredOutputPort = this; else cw->hoveredInputPort = this; } } void PortWidget::onDragLeave(const event::DragLeave &e) { PortWidget *originPort = dynamic_cast(e.origin); if (!originPort) return; CableWidget *cw = app()->scene->rackWidget->cableContainer->incompleteCable; if (cw) { if (type == OUTPUT) cw->hoveredOutputPort = NULL; else cw->hoveredInputPort = NULL; } } } // namespace rack