| @@ -1,6 +1,8 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "app/common.hpp" | #include "app/common.hpp" | ||||
| #include "ui/ScrollWidget.hpp" | #include "ui/ScrollWidget.hpp" | ||||
| #include "widget/ZoomWidget.hpp" | |||||
| #include "app/RackWidget.hpp" | |||||
| namespace rack { | namespace rack { | ||||
| @@ -8,8 +10,14 @@ namespace app { | |||||
| struct RackScrollWidget : ui::ScrollWidget { | struct RackScrollWidget : ui::ScrollWidget { | ||||
| widget::ZoomWidget *zoom; | |||||
| RackWidget *rack; | |||||
| RackScrollWidget(); | |||||
| void step() override; | void step() override; | ||||
| void draw(const DrawArgs &args) override; | void draw(const DrawArgs &args) override; | ||||
| void onHover(const widget::HoverEvent &e) override; | |||||
| void onHoverScroll(const widget::HoverScrollEvent &e) override; | |||||
| }; | }; | ||||
| @@ -1,8 +1,7 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "app/common.hpp" | #include "app/common.hpp" | ||||
| #include "widget/OpaqueWidget.hpp" | #include "widget/OpaqueWidget.hpp" | ||||
| #include "widget/ZoomWidget.hpp" | |||||
| #include "ui/ScrollWidget.hpp" | |||||
| #include "app/RackScrollWidget.hpp" | |||||
| #include "app/RackWidget.hpp" | #include "app/RackWidget.hpp" | ||||
| #include "app/Toolbar.hpp" | #include "app/Toolbar.hpp" | ||||
| @@ -13,9 +12,8 @@ namespace app { | |||||
| struct Scene : widget::OpaqueWidget { | struct Scene : widget::OpaqueWidget { | ||||
| // Convenience variables for accessing important widgets | // Convenience variables for accessing important widgets | ||||
| ui::ScrollWidget *scrollWidget; | |||||
| widget::ZoomWidget *zoomWidget; | |||||
| RackWidget *rackWidget; | |||||
| RackScrollWidget *rackScroll; | |||||
| RackWidget *rack; | |||||
| Toolbar *toolbar; | Toolbar *toolbar; | ||||
| widget::Widget *moduleBrowser; | widget::Widget *moduleBrowser; | ||||
| @@ -37,7 +37,8 @@ struct Param { | |||||
| */ | */ | ||||
| std::string label; | std::string label; | ||||
| /** The numerical unit of measurement appended to the value. | /** The numerical unit of measurement appended to the value. | ||||
| Use a space before units to separate the numerical value from the number (e.g. " semitones", " Hz", " V"), unless the unit should have no space (e.g. "%", "Âş"). | |||||
| Units that are words should have a space to separate the numerical value from the number (e.g. " semitones", " octaves"). | |||||
| Unit abbreviations and symbols should have no space (e.g. "V", "ms", "%", "Âş"). | |||||
| */ | */ | ||||
| std::string unit; | std::string unit; | ||||
| /** Set to 0 for linear, positive for exponential, negative for logarithmic. */ | /** Set to 0 for linear, positive for exponential, negative for logarithmic. */ | ||||
| @@ -43,7 +43,7 @@ struct ModuleResizeHandle : Widget { | |||||
| } | } | ||||
| void onDragStart(const widget::DragStartEvent &e) override { | void onDragStart(const widget::DragStartEvent &e) override { | ||||
| dragX = APP->scene->rackWidget->mousePos.x; | |||||
| dragX = APP->scene->rack->mousePos.x; | |||||
| ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | ||||
| originalBox = m->box; | originalBox = m->box; | ||||
| e.consume(this); | e.consume(this); | ||||
| @@ -52,7 +52,7 @@ struct ModuleResizeHandle : Widget { | |||||
| void onDragMove(const widget::DragMoveEvent &e) override { | void onDragMove(const widget::DragMoveEvent &e) override { | ||||
| ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | ||||
| float newDragX = APP->scene->rackWidget->mousePos.x; | |||||
| float newDragX = APP->scene->rack->mousePos.x; | |||||
| float deltaX = newDragX - dragX; | float deltaX = newDragX - dragX; | ||||
| Rect newBox = originalBox; | Rect newBox = originalBox; | ||||
| @@ -68,7 +68,7 @@ struct ModuleResizeHandle : Widget { | |||||
| newBox.size.x = roundf(newBox.size.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; | newBox.size.x = roundf(newBox.size.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; | ||||
| newBox.pos.x = originalBox.pos.x + originalBox.size.x - newBox.size.x; | newBox.pos.x = originalBox.pos.x + originalBox.size.x - newBox.size.x; | ||||
| } | } | ||||
| APP->scene->rackWidget->requestModuleBox(m, newBox); | |||||
| APP->scene->rack->requestModuleBox(m, newBox); | |||||
| } | } | ||||
| void draw(const DrawArgs &args) override { | void draw(const DrawArgs &args) override { | ||||
| @@ -267,7 +267,7 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||||
| scroll->scrollTo(box); | scroll->scrollTo(box); | ||||
| // Reset touchedParam | // Reset touchedParam | ||||
| APP->scene->rackWidget->touchedParam = NULL; | |||||
| APP->scene->rack->touchedParam = NULL; | |||||
| module->enableLearn(id); | module->enableLearn(id); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| @@ -276,9 +276,9 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||||
| if (!module) | if (!module) | ||||
| return; | return; | ||||
| // Check if a ParamWidget was touched | // Check if a ParamWidget was touched | ||||
| ParamWidget *touchedParam = APP->scene->rackWidget->touchedParam; | |||||
| ParamWidget *touchedParam = APP->scene->rack->touchedParam; | |||||
| if (touchedParam) { | if (touchedParam) { | ||||
| APP->scene->rackWidget->touchedParam = NULL; | |||||
| APP->scene->rack->touchedParam = NULL; | |||||
| int moduleId = touchedParam->paramQuantity->module->id; | int moduleId = touchedParam->paramQuantity->module->id; | ||||
| int paramId = touchedParam->paramQuantity->paramId; | int paramId = touchedParam->paramQuantity->paramId; | ||||
| module->learnParam(id, moduleId, paramId); | module->learnParam(id, moduleId, paramId); | ||||
| @@ -343,7 +343,7 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||||
| ParamHandle *paramHandle = &module->paramHandles[id]; | ParamHandle *paramHandle = &module->paramHandles[id]; | ||||
| if (paramHandle->moduleId < 0) | if (paramHandle->moduleId < 0) | ||||
| return ""; | return ""; | ||||
| ModuleWidget *mw = APP->scene->rackWidget->getModule(paramHandle->moduleId); | |||||
| ModuleWidget *mw = APP->scene->rack->getModule(paramHandle->moduleId); | |||||
| if (!mw) | if (!mw) | ||||
| return ""; | return ""; | ||||
| // Get the Module from the ModuleWidget instead of the ParamHandle. | // Get the Module from the ModuleWidget instead of the ParamHandle. | ||||
| @@ -120,25 +120,25 @@ void CableWidget::setInput(PortWidget *inputPort) { | |||||
| math::Vec CableWidget::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->rack); | |||||
| } | } | ||||
| else if (hoveredOutputPort) { | else if (hoveredOutputPort) { | ||||
| return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), APP->scene->rackWidget); | |||||
| return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), APP->scene->rack); | |||||
| } | } | ||||
| else { | else { | ||||
| return APP->scene->rackWidget->mousePos; | |||||
| return APP->scene->rack->mousePos; | |||||
| } | } | ||||
| } | } | ||||
| math::Vec CableWidget::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->rack); | |||||
| } | } | ||||
| else if (hoveredInputPort) { | else if (hoveredInputPort) { | ||||
| return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), APP->scene->rackWidget); | |||||
| return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), APP->scene->rack); | |||||
| } | } | ||||
| else { | else { | ||||
| return APP->scene->rackWidget->mousePos; | |||||
| return APP->scene->rack->mousePos; | |||||
| } | } | ||||
| } | } | ||||
| @@ -162,14 +162,14 @@ void CableWidget::fromJson(json_t *rootJ) { | |||||
| json_t *outputModuleIdJ = json_object_get(rootJ, "outputModuleId"); | json_t *outputModuleIdJ = json_object_get(rootJ, "outputModuleId"); | ||||
| if (!outputModuleIdJ) return; | if (!outputModuleIdJ) return; | ||||
| int outputModuleId = json_integer_value(outputModuleIdJ); | int outputModuleId = json_integer_value(outputModuleIdJ); | ||||
| ModuleWidget *outputModule = APP->scene->rackWidget->getModule(outputModuleId); | |||||
| ModuleWidget *outputModule = APP->scene->rack->getModule(outputModuleId); | |||||
| if (!outputModule) return; | if (!outputModule) return; | ||||
| // inputModuleId | // inputModuleId | ||||
| json_t *inputModuleIdJ = json_object_get(rootJ, "inputModuleId"); | json_t *inputModuleIdJ = json_object_get(rootJ, "inputModuleId"); | ||||
| if (!inputModuleIdJ) return; | if (!inputModuleIdJ) return; | ||||
| int inputModuleId = json_integer_value(inputModuleIdJ); | int inputModuleId = json_integer_value(inputModuleIdJ); | ||||
| ModuleWidget *inputModule = APP->scene->rackWidget->getModule(inputModuleId); | |||||
| ModuleWidget *inputModule = APP->scene->rack->getModule(inputModuleId); | |||||
| if (!inputModule) return; | if (!inputModule) return; | ||||
| // outputId | // outputId | ||||
| @@ -250,7 +250,7 @@ void CableWidget::drawPlugs(const DrawArgs &args) { | |||||
| math::Vec inputPos = getInputPos(); | math::Vec inputPos = getInputPos(); | ||||
| // Draw plug if the cable is on top, or if the cable is incomplete | // Draw plug if the cable is on top, or if the cable is incomplete | ||||
| if (!isComplete() || APP->scene->rackWidget->getTopCable(outputPort) == this) { | |||||
| if (!isComplete() || APP->scene->rack->getTopCable(outputPort) == this) { | |||||
| drawPlug(args.vg, outputPos, color); | drawPlug(args.vg, outputPos, color); | ||||
| if (isComplete()) { | if (isComplete()) { | ||||
| // Draw plug light | // Draw plug light | ||||
| @@ -261,7 +261,7 @@ void CableWidget::drawPlugs(const DrawArgs &args) { | |||||
| } | } | ||||
| } | } | ||||
| if (!isComplete() || APP->scene->rackWidget->getTopCable(inputPort) == this) { | |||||
| if (!isComplete() || APP->scene->rack->getTopCable(inputPort) == this) { | |||||
| drawPlug(args.vg, inputPos, color); | drawPlug(args.vg, inputPos, color); | ||||
| if (isComplete()) { | if (isComplete()) { | ||||
| nvgSave(args.vg); | nvgSave(args.vg); | ||||
| @@ -493,7 +493,7 @@ inline void ModelBox::onButton(const widget::ButtonEvent &e) { | |||||
| // Create module | // Create module | ||||
| ModuleWidget *moduleWidget = model->createModuleWidget(); | ModuleWidget *moduleWidget = model->createModuleWidget(); | ||||
| assert(moduleWidget); | assert(moduleWidget); | ||||
| APP->scene->rackWidget->addModuleAtMouse(moduleWidget); | |||||
| APP->scene->rack->addModuleAtMouse(moduleWidget); | |||||
| // Pretend the moduleWidget was clicked so it can be dragged in the RackWidget | // Pretend the moduleWidget was clicked so it can be dragged in the RackWidget | ||||
| e.consume(moduleWidget); | e.consume(moduleWidget); | ||||
| @@ -352,7 +352,7 @@ void ModuleWidget::onHoverKey(const widget::HoverKeyEvent &e) { | |||||
| void ModuleWidget::onDragStart(const widget::DragStartEvent &e) { | void ModuleWidget::onDragStart(const widget::DragStartEvent &e) { | ||||
| oldPos = box.pos; | oldPos = box.pos; | ||||
| dragPos = APP->scene->rackWidget->mousePos.minus(box.pos); | |||||
| dragPos = APP->scene->rack->mousePos.minus(box.pos); | |||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| @@ -370,8 +370,8 @@ void ModuleWidget::onDragEnd(const widget::DragEndEvent &e) { | |||||
| void ModuleWidget::onDragMove(const widget::DragMoveEvent &e) { | void ModuleWidget::onDragMove(const widget::DragMoveEvent &e) { | ||||
| if (!settings.lockModules) { | if (!settings.lockModules) { | ||||
| math::Rect newBox = box; | math::Rect newBox = box; | ||||
| newBox.pos = APP->scene->rackWidget->mousePos.minus(dragPos); | |||||
| APP->scene->rackWidget->requestModuleBoxNearest(this, newBox); | |||||
| newBox.pos = APP->scene->rack->mousePos.minus(dragPos); | |||||
| APP->scene->rack->requestModuleBoxNearest(this, newBox); | |||||
| } | } | ||||
| } | } | ||||
| @@ -635,10 +635,10 @@ void ModuleWidget::saveDialog() { | |||||
| void ModuleWidget::disconnect() { | void ModuleWidget::disconnect() { | ||||
| for (PortWidget *input : inputs) { | for (PortWidget *input : inputs) { | ||||
| APP->scene->rackWidget->clearCablesOnPort(input); | |||||
| APP->scene->rack->clearCablesOnPort(input); | |||||
| } | } | ||||
| for (PortWidget *output : outputs) { | for (PortWidget *output : outputs) { | ||||
| APP->scene->rackWidget->clearCablesOnPort(output); | |||||
| APP->scene->rack->clearCablesOnPort(output); | |||||
| } | } | ||||
| } | } | ||||
| @@ -675,7 +675,7 @@ void ModuleWidget::randomizeAction() { | |||||
| static void disconnectActions(ModuleWidget *mw, history::ComplexAction *complexAction) { | static void disconnectActions(ModuleWidget *mw, history::ComplexAction *complexAction) { | ||||
| // Add CableRemove action for all cables attached to outputs | // Add CableRemove action for all cables attached to outputs | ||||
| for (PortWidget* output : mw->outputs) { | for (PortWidget* output : mw->outputs) { | ||||
| for (CableWidget *cw : APP->scene->rackWidget->getCablesOnPort(output)) { | |||||
| for (CableWidget *cw : APP->scene->rack->getCablesOnPort(output)) { | |||||
| if (!cw->isComplete()) | if (!cw->isComplete()) | ||||
| continue; | continue; | ||||
| // history::CableRemove | // history::CableRemove | ||||
| @@ -686,7 +686,7 @@ static void disconnectActions(ModuleWidget *mw, history::ComplexAction *complexA | |||||
| } | } | ||||
| // Add CableRemove action for all cables attached to inputs | // Add CableRemove action for all cables attached to inputs | ||||
| for (PortWidget* input : mw->inputs) { | for (PortWidget* input : mw->inputs) { | ||||
| for (CableWidget *cw : APP->scene->rackWidget->getCablesOnPort(input)) { | |||||
| for (CableWidget *cw : APP->scene->rack->getCablesOnPort(input)) { | |||||
| if (!cw->isComplete()) | if (!cw->isComplete()) | ||||
| continue; | continue; | ||||
| // Avoid creating duplicate actions for self-patched cables | // Avoid creating duplicate actions for self-patched cables | ||||
| @@ -717,7 +717,7 @@ void ModuleWidget::cloneAction() { | |||||
| clonedModuleWidget->fromJson(moduleJ); | clonedModuleWidget->fromJson(moduleJ); | ||||
| json_decref(moduleJ); | json_decref(moduleJ); | ||||
| APP->scene->rackWidget->addModuleAtMouse(clonedModuleWidget); | |||||
| APP->scene->rack->addModuleAtMouse(clonedModuleWidget); | |||||
| // history::ModuleAdd | // history::ModuleAdd | ||||
| history::ModuleAdd *h = new history::ModuleAdd; | history::ModuleAdd *h = new history::ModuleAdd; | ||||
| @@ -749,7 +749,7 @@ void ModuleWidget::removeAction() { | |||||
| APP->history->push(complexAction); | APP->history->push(complexAction); | ||||
| // This disconnects cables, removes the module, and transfers ownership to caller | // This disconnects cables, removes the module, and transfers ownership to caller | ||||
| APP->scene->rackWidget->removeModule(this); | |||||
| APP->scene->rack->removeModule(this); | |||||
| delete this; | delete this; | ||||
| } | } | ||||
| @@ -150,7 +150,7 @@ void ParamWidget::onButton(const widget::ButtonEvent &e) { | |||||
| // Touch parameter | // Touch parameter | ||||
| if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == 0) { | if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == 0) { | ||||
| if (paramQuantity) { | if (paramQuantity) { | ||||
| APP->scene->rackWidget->touchedParam = this; | |||||
| APP->scene->rack->touchedParam = this; | |||||
| } | } | ||||
| } | } | ||||
| @@ -30,7 +30,7 @@ PortWidget::~PortWidget() { | |||||
| delete plugLight; | delete plugLight; | ||||
| // HACK | // HACK | ||||
| if (module) | if (module) | ||||
| APP->scene->rackWidget->clearCablesOnPort(this); | |||||
| APP->scene->rack->clearCablesOnPort(this); | |||||
| } | } | ||||
| void PortWidget::step() { | void PortWidget::step() { | ||||
| @@ -50,7 +50,7 @@ void PortWidget::step() { | |||||
| } | } | ||||
| void PortWidget::draw(const DrawArgs &args) { | void PortWidget::draw(const DrawArgs &args) { | ||||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||||
| if (cw) { | if (cw) { | ||||
| // Dim the PortWidget if the active cable cannot plug into this PortWidget | // Dim the PortWidget if the active cable cannot plug into this PortWidget | ||||
| if (type == OUTPUT ? cw->outputPort : cw->inputPort) | if (type == OUTPUT ? cw->outputPort : cw->inputPort) | ||||
| @@ -61,14 +61,14 @@ void PortWidget::draw(const DrawArgs &args) { | |||||
| void PortWidget::onButton(const widget::ButtonEvent &e) { | void PortWidget::onButton(const widget::ButtonEvent &e) { | ||||
| if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | ||||
| CableWidget *cw = APP->scene->rackWidget->getTopCable(this); | |||||
| CableWidget *cw = APP->scene->rack->getTopCable(this); | |||||
| if (cw) { | if (cw) { | ||||
| // history::CableRemove | // history::CableRemove | ||||
| history::CableRemove *h = new history::CableRemove; | history::CableRemove *h = new history::CableRemove; | ||||
| h->setCable(cw); | h->setCable(cw); | ||||
| APP->history->push(h); | APP->history->push(h); | ||||
| APP->scene->rackWidget->removeCable(cw); | |||||
| APP->scene->rack->removeCable(cw); | |||||
| delete cw; | delete cw; | ||||
| } | } | ||||
| } | } | ||||
| @@ -91,7 +91,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||||
| // Keep cable NULL. Will be created below | // Keep cable NULL. Will be created below | ||||
| } | } | ||||
| else { | else { | ||||
| CableWidget *topCw = APP->scene->rackWidget->getTopCable(this); | |||||
| CableWidget *topCw = APP->scene->rack->getTopCable(this); | |||||
| if (topCw) { | if (topCw) { | ||||
| cw = new CableWidget; | cw = new CableWidget; | ||||
| cw->setOutput(topCw->outputPort); | cw->setOutput(topCw->outputPort); | ||||
| @@ -100,7 +100,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||||
| } | } | ||||
| else { | else { | ||||
| // Grab cable on top of stack | // Grab cable on top of stack | ||||
| cw = APP->scene->rackWidget->getTopCable(this); | |||||
| cw = APP->scene->rack->getTopCable(this); | |||||
| if (cw) { | if (cw) { | ||||
| // history::CableRemove | // history::CableRemove | ||||
| @@ -109,7 +109,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||||
| APP->history->push(h); | APP->history->push(h); | ||||
| // Disconnect and reuse existing cable | // Disconnect and reuse existing cable | ||||
| APP->scene->rackWidget->removeCable(cw); | |||||
| APP->scene->rack->removeCable(cw); | |||||
| if (type == OUTPUT) | if (type == OUTPUT) | ||||
| cw->setOutput(NULL); | cw->setOutput(NULL); | ||||
| else | else | ||||
| @@ -126,14 +126,14 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||||
| cw->setInput(this); | cw->setInput(this); | ||||
| } | } | ||||
| APP->scene->rackWidget->setIncompleteCable(cw); | |||||
| APP->scene->rack->setIncompleteCable(cw); | |||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| void PortWidget::onDragEnd(const widget::DragEndEvent &e) { | void PortWidget::onDragEnd(const widget::DragEndEvent &e) { | ||||
| CableWidget *cw = APP->scene->rackWidget->releaseIncompleteCable(); | |||||
| CableWidget *cw = APP->scene->rack->releaseIncompleteCable(); | |||||
| if (cw->isComplete()) { | if (cw->isComplete()) { | ||||
| APP->scene->rackWidget->addCable(cw); | |||||
| APP->scene->rack->addCable(cw); | |||||
| // history::CableAdd | // history::CableAdd | ||||
| history::CableAdd *h = new history::CableAdd; | history::CableAdd *h = new history::CableAdd; | ||||
| @@ -148,11 +148,11 @@ void PortWidget::onDragEnd(const widget::DragEndEvent &e) { | |||||
| void PortWidget::onDragDrop(const widget::DragDropEvent &e) { | void PortWidget::onDragDrop(const widget::DragDropEvent &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) { | ||||
| if (APP->scene->rackWidget->getTopCable(this)) | |||||
| if (APP->scene->rack->getTopCable(this)) | |||||
| return; | return; | ||||
| } | } | ||||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||||
| if (cw) { | if (cw) { | ||||
| cw->hoveredOutputPort = cw->hoveredInputPort = NULL; | cw->hoveredOutputPort = cw->hoveredInputPort = NULL; | ||||
| if (type == OUTPUT) | if (type == OUTPUT) | ||||
| @@ -165,11 +165,11 @@ void PortWidget::onDragDrop(const widget::DragDropEvent &e) { | |||||
| void PortWidget::onDragEnter(const widget::DragEnterEvent &e) { | void PortWidget::onDragEnter(const widget::DragEnterEvent &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) { | ||||
| if (APP->scene->rackWidget->getTopCable(this)) | |||||
| if (APP->scene->rack->getTopCable(this)) | |||||
| return; | return; | ||||
| } | } | ||||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||||
| if (cw) { | if (cw) { | ||||
| if (type == OUTPUT) | if (type == OUTPUT) | ||||
| cw->hoveredOutputPort = this; | cw->hoveredOutputPort = this; | ||||
| @@ -184,7 +184,7 @@ void PortWidget::onDragLeave(const widget::DragLeaveEvent &e) { | |||||
| if (!originPort) | if (!originPort) | ||||
| return; | return; | ||||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||||
| if (cw) { | if (cw) { | ||||
| if (type == OUTPUT) | if (type == OUTPUT) | ||||
| cw->hoveredOutputPort = NULL; | cw->hoveredOutputPort = NULL; | ||||
| @@ -2,17 +2,41 @@ | |||||
| #include "app/Scene.hpp" | #include "app/Scene.hpp" | ||||
| #include "window.hpp" | #include "window.hpp" | ||||
| #include "app.hpp" | #include "app.hpp" | ||||
| #include "settings.hpp" | |||||
| namespace rack { | namespace rack { | ||||
| namespace app { | namespace app { | ||||
| RackScrollWidget::RackScrollWidget() { | |||||
| zoom = new widget::ZoomWidget; | |||||
| container->addChild(zoom); | |||||
| rack = new RackWidget; | |||||
| zoom->addChild(rack); | |||||
| } | |||||
| void RackScrollWidget::step() { | void RackScrollWidget::step() { | ||||
| // Set ZoomWidget's zoom every few frames | |||||
| int frame = APP->window->frame; | |||||
| if (frame % 10 == 0) { | |||||
| zoom->setZoom(std::round(settings.zoom * 100) / 100); | |||||
| } | |||||
| // Resize RackWidget to be a bit larger than the viewport | |||||
| rack->box.size = box.size | |||||
| .minus(container->box.pos) | |||||
| .plus(math::Vec(500, 500)) | |||||
| .div(zoom->zoom); | |||||
| // Resize ZoomWidget | |||||
| zoom->box.size = rack->box.size.mult(zoom->zoom); | |||||
| // Scroll rack if dragging cable near the edge of the screen | |||||
| 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 | |||||
| if (APP->scene->rackWidget->incompleteCable) { | |||||
| if (rack->incompleteCable) { | |||||
| 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) | ||||
| @@ -24,6 +48,7 @@ void RackScrollWidget::step() { | |||||
| if (pos.y >= viewport.pos.y + viewport.size.y - margin) | if (pos.y >= viewport.pos.y + viewport.size.y - margin) | ||||
| offset.y += speed; | offset.y += speed; | ||||
| } | } | ||||
| ScrollWidget::step(); | ScrollWidget::step(); | ||||
| } | } | ||||
| @@ -32,6 +57,43 @@ void RackScrollWidget::draw(const DrawArgs &args) { | |||||
| ScrollWidget::draw(args); | ScrollWidget::draw(args); | ||||
| } | } | ||||
| void RackScrollWidget::onHover(const widget::HoverEvent &e) { | |||||
| if (!APP->event->selectedWidget) { | |||||
| // Scroll with arrow keys | |||||
| float arrowSpeed = 30.0; | |||||
| if ((APP->window->getMods() & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL |GLFW_MOD_SHIFT)) | |||||
| arrowSpeed /= 16.0; | |||||
| else if ((APP->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) | |||||
| arrowSpeed *= 4.0; | |||||
| else if ((APP->window->getMods() & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) | |||||
| arrowSpeed /= 4.0; | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_LEFT) == GLFW_PRESS) { | |||||
| offset.x -= arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_RIGHT) == GLFW_PRESS) { | |||||
| offset.x += arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_UP) == GLFW_PRESS) { | |||||
| offset.y -= arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_DOWN) == GLFW_PRESS) { | |||||
| offset.y += arrowSpeed; | |||||
| } | |||||
| } | |||||
| ScrollWidget::onHover(e); | |||||
| } | |||||
| void RackScrollWidget::onHoverScroll(const widget::HoverScrollEvent &e) { | |||||
| if ((APP->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) { | |||||
| e.consume(this); | |||||
| return; | |||||
| } | |||||
| ScrollWidget::onHoverScroll(e); | |||||
| } | |||||
| } // namespace app | } // namespace app | ||||
| } // namespace rack | } // namespace rack | ||||
| @@ -122,37 +122,12 @@ void RackWidget::draw(const DrawArgs &args) { | |||||
| } | } | ||||
| void RackWidget::onHover(const widget::HoverEvent &e) { | void RackWidget::onHover(const widget::HoverEvent &e) { | ||||
| if (!APP->event->selectedWidget) { | |||||
| // Scroll with arrow keys | |||||
| float arrowSpeed = 30.0; | |||||
| if ((APP->window->getMods() & WINDOW_MOD_MASK) == (WINDOW_MOD_CTRL |GLFW_MOD_SHIFT)) | |||||
| arrowSpeed /= 16.0; | |||||
| else if ((APP->window->getMods() & WINDOW_MOD_MASK) == WINDOW_MOD_CTRL) | |||||
| arrowSpeed *= 4.0; | |||||
| else if ((APP->window->getMods() & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) | |||||
| arrowSpeed /= 4.0; | |||||
| ui::ScrollWidget *scrollWidget = APP->scene->scrollWidget; | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_LEFT) == GLFW_PRESS) { | |||||
| scrollWidget->offset.x -= arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_RIGHT) == GLFW_PRESS) { | |||||
| scrollWidget->offset.x += arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_UP) == GLFW_PRESS) { | |||||
| scrollWidget->offset.y -= arrowSpeed; | |||||
| } | |||||
| if (glfwGetKey(APP->window->win, GLFW_KEY_DOWN) == GLFW_PRESS) { | |||||
| scrollWidget->offset.y += arrowSpeed; | |||||
| } | |||||
| } | |||||
| widget::OpaqueWidget::onHover(e); | |||||
| mousePos = e.pos; | mousePos = e.pos; | ||||
| OpaqueWidget::onHover(e); | |||||
| } | } | ||||
| void RackWidget::onHoverKey(const widget::HoverKeyEvent &e) { | void RackWidget::onHoverKey(const widget::HoverKeyEvent &e) { | ||||
| widget::OpaqueWidget::onHoverKey(e); | |||||
| OpaqueWidget::onHoverKey(e); | |||||
| if (e.getConsumed() != this) | if (e.getConsumed() != this) | ||||
| return; | return; | ||||
| @@ -168,12 +143,12 @@ void RackWidget::onHoverKey(const widget::HoverKeyEvent &e) { | |||||
| } | } | ||||
| void RackWidget::onDragHover(const widget::DragHoverEvent &e) { | void RackWidget::onDragHover(const widget::DragHoverEvent &e) { | ||||
| widget::OpaqueWidget::onDragHover(e); | |||||
| OpaqueWidget::onDragHover(e); | |||||
| mousePos = e.pos; | mousePos = e.pos; | ||||
| } | } | ||||
| void RackWidget::onButton(const widget::ButtonEvent &e) { | void RackWidget::onButton(const widget::ButtonEvent &e) { | ||||
| widget::OpaqueWidget::onButton(e); | |||||
| OpaqueWidget::onButton(e); | |||||
| if (e.getConsumed() == this) { | if (e.getConsumed() == this) { | ||||
| if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | ||||
| APP->scene->moduleBrowser->show(); | APP->scene->moduleBrowser->show(); | ||||
| @@ -183,7 +158,7 @@ void RackWidget::onButton(const widget::ButtonEvent &e) { | |||||
| void RackWidget::onZoom(const widget::ZoomEvent &e) { | void RackWidget::onZoom(const widget::ZoomEvent &e) { | ||||
| rails->box.size = math::Vec(); | rails->box.size = math::Vec(); | ||||
| widget::OpaqueWidget::onZoom(e); | |||||
| OpaqueWidget::onZoom(e); | |||||
| } | } | ||||
| void RackWidget::clear() { | void RackWidget::clear() { | ||||
| @@ -1,9 +1,8 @@ | |||||
| #include "system.hpp" | |||||
| #include "network.hpp" | |||||
| #include "app/Scene.hpp" | #include "app/Scene.hpp" | ||||
| #include "app/ModuleBrowser.hpp" | #include "app/ModuleBrowser.hpp" | ||||
| #include "app/RackScrollWidget.hpp" | |||||
| #include "app.hpp" | #include "app.hpp" | ||||
| #include "system.hpp" | |||||
| #include "network.hpp" | |||||
| #include "history.hpp" | #include "history.hpp" | ||||
| #include "settings.hpp" | #include "settings.hpp" | ||||
| #include "patch.hpp" | #include "patch.hpp" | ||||
| @@ -17,23 +16,17 @@ namespace app { | |||||
| Scene::Scene() { | Scene::Scene() { | ||||
| scrollWidget = new RackScrollWidget; | |||||
| { | |||||
| zoomWidget = new widget::ZoomWidget; | |||||
| { | |||||
| rackWidget = new RackWidget; | |||||
| zoomWidget->addChild(rackWidget); | |||||
| } | |||||
| scrollWidget->container->addChild(zoomWidget); | |||||
| } | |||||
| addChild(scrollWidget); | |||||
| rackScroll = new RackScrollWidget; | |||||
| addChild(rackScroll); | |||||
| rack = rackScroll->rack; | |||||
| toolbar = new Toolbar; | toolbar = new Toolbar; | ||||
| addChild(toolbar); | addChild(toolbar); | ||||
| scrollWidget->box.pos.y = toolbar->box.size.y; | |||||
| rackScroll->box.pos.y = toolbar->box.size.y; | |||||
| moduleBrowser = moduleBrowserCreate(); | moduleBrowser = moduleBrowserCreate(); | ||||
| moduleBrowser->visible = false; | |||||
| moduleBrowser->hide(); | |||||
| addChild(moduleBrowser); | addChild(moduleBrowser); | ||||
| } | } | ||||
| @@ -43,17 +36,7 @@ Scene::~Scene() { | |||||
| void Scene::step() { | void Scene::step() { | ||||
| // Resize owned descendants | // Resize owned descendants | ||||
| toolbar->box.size.x = box.size.x; | toolbar->box.size.x = box.size.x; | ||||
| scrollWidget->box.size = box.size.minus(scrollWidget->box.pos); | |||||
| // Resize to be a bit larger than the ui::ScrollWidget viewport | |||||
| rackWidget->box.size = scrollWidget->box.size | |||||
| .minus(scrollWidget->container->box.pos) | |||||
| .plus(math::Vec(500, 500)) | |||||
| .div(zoomWidget->zoom); | |||||
| OpaqueWidget::step(); | |||||
| zoomWidget->box.size = rackWidget->box.size.mult(zoomWidget->zoom); | |||||
| rackScroll->box.size = box.size.minus(rackScroll->box.pos); | |||||
| // Autosave every 15 seconds | // Autosave every 15 seconds | ||||
| double time = glfwGetTime(); | double time = glfwGetTime(); | ||||
| @@ -63,11 +46,6 @@ void Scene::step() { | |||||
| settings.save(asset::user("settings.json")); | settings.save(asset::user("settings.json")); | ||||
| } | } | ||||
| // Set zoom every few frames | |||||
| int frame = APP->window->frame; | |||||
| if (frame % 10 == 0) | |||||
| zoomWidget->setZoom(std::round(settings.zoom * 100) / 100); | |||||
| // Request latest version from server | // Request latest version from server | ||||
| if (!devMode && checkVersion && !checkedVersion) { | if (!devMode && checkVersion && !checkedVersion) { | ||||
| std::thread t(&Scene::runCheckVersion, this); | std::thread t(&Scene::runCheckVersion, this); | ||||
| @@ -85,6 +63,8 @@ void Scene::step() { | |||||
| } | } | ||||
| latestVersion = ""; | latestVersion = ""; | ||||
| } | } | ||||
| OpaqueWidget::step(); | |||||
| } | } | ||||
| void Scene::draw(const DrawArgs &args) { | void Scene::draw(const DrawArgs &args) { | ||||
| @@ -48,9 +48,9 @@ void ModuleAdd::setModule(app::ModuleWidget *mw) { | |||||
| } | } | ||||
| void ModuleAdd::undo() { | void ModuleAdd::undo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| APP->scene->rackWidget->removeModule(mw); | |||||
| APP->scene->rack->removeModule(mw); | |||||
| delete mw; | delete mw; | ||||
| } | } | ||||
| @@ -61,31 +61,31 @@ void ModuleAdd::redo() { | |||||
| mw->module->id = moduleId; | mw->module->id = moduleId; | ||||
| mw->box.pos = pos; | mw->box.pos = pos; | ||||
| mw->fromJson(moduleJ); | mw->fromJson(moduleJ); | ||||
| APP->scene->rackWidget->addModule(mw); | |||||
| APP->scene->rack->addModule(mw); | |||||
| } | } | ||||
| void ModuleMove::undo() { | void ModuleMove::undo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->box.pos = oldPos; | mw->box.pos = oldPos; | ||||
| } | } | ||||
| void ModuleMove::redo() { | void ModuleMove::redo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->box.pos = newPos; | mw->box.pos = newPos; | ||||
| } | } | ||||
| void ModuleBypass::undo() { | void ModuleBypass::undo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| APP->engine->bypassModule(mw->module, !bypass); | APP->engine->bypassModule(mw->module, !bypass); | ||||
| } | } | ||||
| void ModuleBypass::redo() { | void ModuleBypass::redo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| APP->engine->bypassModule(mw->module, bypass); | APP->engine->bypassModule(mw->module, bypass); | ||||
| } | } | ||||
| @@ -97,26 +97,26 @@ ModuleChange::~ModuleChange() { | |||||
| } | } | ||||
| void ModuleChange::undo() { | void ModuleChange::undo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->fromJson(oldModuleJ); | mw->fromJson(oldModuleJ); | ||||
| } | } | ||||
| void ModuleChange::redo() { | void ModuleChange::redo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->fromJson(newModuleJ); | mw->fromJson(newModuleJ); | ||||
| } | } | ||||
| void ParamChange::undo() { | void ParamChange::undo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->module->params[paramId].value = oldValue; | mw->module->params[paramId].value = oldValue; | ||||
| } | } | ||||
| void ParamChange::redo() { | void ParamChange::redo() { | ||||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||||
| assert(mw); | assert(mw); | ||||
| mw->module->params[paramId].value = newValue; | mw->module->params[paramId].value = newValue; | ||||
| } | } | ||||
| @@ -136,8 +136,8 @@ void CableAdd::setCable(app::CableWidget *cw) { | |||||
| } | } | ||||
| void CableAdd::undo() { | void CableAdd::undo() { | ||||
| app::CableWidget *cw = APP->scene->rackWidget->getCable(cableId); | |||||
| APP->scene->rackWidget->removeCable(cw); | |||||
| app::CableWidget *cw = APP->scene->rack->getCable(cableId); | |||||
| APP->scene->rack->removeCable(cw); | |||||
| delete cw; | delete cw; | ||||
| } | } | ||||
| @@ -145,13 +145,13 @@ void CableAdd::redo() { | |||||
| app::CableWidget *cw = new app::CableWidget; | app::CableWidget *cw = new app::CableWidget; | ||||
| cw->cable->id = cableId; | cw->cable->id = cableId; | ||||
| app::ModuleWidget *outputModule = APP->scene->rackWidget->getModule(outputModuleId); | |||||
| app::ModuleWidget *outputModule = APP->scene->rack->getModule(outputModuleId); | |||||
| assert(outputModule); | assert(outputModule); | ||||
| app::PortWidget *outputPort = outputModule->getOutput(outputId); | app::PortWidget *outputPort = outputModule->getOutput(outputId); | ||||
| assert(outputPort); | assert(outputPort); | ||||
| cw->setOutput(outputPort); | cw->setOutput(outputPort); | ||||
| app::ModuleWidget *inputModule = APP->scene->rackWidget->getModule(inputModuleId); | |||||
| app::ModuleWidget *inputModule = APP->scene->rack->getModule(inputModuleId); | |||||
| assert(inputModule); | assert(inputModule); | ||||
| app::PortWidget *inputPort = inputModule->getInput(inputId); | app::PortWidget *inputPort = inputModule->getInput(inputId); | ||||
| assert(inputPort); | assert(inputPort); | ||||
| @@ -159,7 +159,7 @@ void CableAdd::redo() { | |||||
| cw->color = color; | cw->color = color; | ||||
| APP->scene->rackWidget->addCable(cw); | |||||
| APP->scene->rack->addCable(cw); | |||||
| } | } | ||||
| @@ -59,8 +59,8 @@ void PatchManager::init(std::string path) { | |||||
| void PatchManager::reset() { | void PatchManager::reset() { | ||||
| APP->history->clear(); | APP->history->clear(); | ||||
| APP->scene->rackWidget->clear(); | |||||
| APP->scene->scrollWidget->offset = math::Vec(0, 0); | |||||
| APP->scene->rack->clear(); | |||||
| APP->scene->rackScroll->offset = math::Vec(0, 0); | |||||
| // Fails silently if file does not exist | // Fails silently if file does not exist | ||||
| load(asset::user("template.vcv")); | load(asset::user("template.vcv")); | ||||
| legacy = 0; | legacy = 0; | ||||
| @@ -168,8 +168,8 @@ bool PatchManager::load(std::string path) { | |||||
| }); | }); | ||||
| APP->history->clear(); | APP->history->clear(); | ||||
| APP->scene->rackWidget->clear(); | |||||
| APP->scene->scrollWidget->offset = math::Vec(0, 0); | |||||
| APP->scene->rack->clear(); | |||||
| APP->scene->rackScroll->offset = math::Vec(0, 0); | |||||
| fromJson(rootJ); | fromJson(rootJ); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -215,7 +215,7 @@ void PatchManager::disconnectDialog() { | |||||
| // 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; | ||||
| APP->scene->rackWidget->clearCablesAction(); | |||||
| APP->scene->rack->clearCablesAction(); | |||||
| } | } | ||||
| json_t *PatchManager::toJson() { | json_t *PatchManager::toJson() { | ||||
| @@ -227,7 +227,7 @@ json_t *PatchManager::toJson() { | |||||
| json_object_set_new(rootJ, "version", versionJ); | json_object_set_new(rootJ, "version", versionJ); | ||||
| // Merge with RackWidget JSON | // Merge with RackWidget JSON | ||||
| json_t *rackJ = APP->scene->rackWidget->toJson(); | |||||
| json_t *rackJ = APP->scene->rack->toJson(); | |||||
| // Merge with rootJ | // Merge with rootJ | ||||
| json_object_update(rootJ, rackJ); | json_object_update(rootJ, rackJ); | ||||
| json_decref(rackJ); | json_decref(rackJ); | ||||
| @@ -259,7 +259,7 @@ void PatchManager::fromJson(json_t *rootJ) { | |||||
| INFO("Loading patch using legacy mode %d", legacy); | INFO("Loading patch using legacy mode %d", legacy); | ||||
| } | } | ||||
| APP->scene->rackWidget->fromJson(rootJ); | |||||
| APP->scene->rack->fromJson(rootJ); | |||||
| // Display a message if we have something to say | // Display a message if we have something to say | ||||
| if (!warningLog.empty()) { | if (!warningLog.empty()) { | ||||