| @@ -1,6 +1,8 @@ | |||
| #pragma once | |||
| #include "app/common.hpp" | |||
| #include "ui/ScrollWidget.hpp" | |||
| #include "widget/ZoomWidget.hpp" | |||
| #include "app/RackWidget.hpp" | |||
| namespace rack { | |||
| @@ -8,8 +10,14 @@ namespace app { | |||
| struct RackScrollWidget : ui::ScrollWidget { | |||
| widget::ZoomWidget *zoom; | |||
| RackWidget *rack; | |||
| RackScrollWidget(); | |||
| void step() 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 | |||
| #include "app/common.hpp" | |||
| #include "widget/OpaqueWidget.hpp" | |||
| #include "widget/ZoomWidget.hpp" | |||
| #include "ui/ScrollWidget.hpp" | |||
| #include "app/RackScrollWidget.hpp" | |||
| #include "app/RackWidget.hpp" | |||
| #include "app/Toolbar.hpp" | |||
| @@ -13,9 +12,8 @@ namespace app { | |||
| struct Scene : widget::OpaqueWidget { | |||
| // Convenience variables for accessing important widgets | |||
| ui::ScrollWidget *scrollWidget; | |||
| widget::ZoomWidget *zoomWidget; | |||
| RackWidget *rackWidget; | |||
| RackScrollWidget *rackScroll; | |||
| RackWidget *rack; | |||
| Toolbar *toolbar; | |||
| widget::Widget *moduleBrowser; | |||
| @@ -37,7 +37,8 @@ struct Param { | |||
| */ | |||
| std::string label; | |||
| /** 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; | |||
| /** 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 { | |||
| dragX = APP->scene->rackWidget->mousePos.x; | |||
| dragX = APP->scene->rack->mousePos.x; | |||
| ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | |||
| originalBox = m->box; | |||
| e.consume(this); | |||
| @@ -52,7 +52,7 @@ struct ModuleResizeHandle : Widget { | |||
| void onDragMove(const widget::DragMoveEvent &e) override { | |||
| ModuleWidget *m = getAncestorOfType<ModuleWidget>(); | |||
| float newDragX = APP->scene->rackWidget->mousePos.x; | |||
| float newDragX = APP->scene->rack->mousePos.x; | |||
| float deltaX = newDragX - dragX; | |||
| Rect newBox = originalBox; | |||
| @@ -68,7 +68,7 @@ struct ModuleResizeHandle : Widget { | |||
| 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; | |||
| } | |||
| APP->scene->rackWidget->requestModuleBox(m, newBox); | |||
| APP->scene->rack->requestModuleBox(m, newBox); | |||
| } | |||
| void draw(const DrawArgs &args) override { | |||
| @@ -267,7 +267,7 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||
| scroll->scrollTo(box); | |||
| // Reset touchedParam | |||
| APP->scene->rackWidget->touchedParam = NULL; | |||
| APP->scene->rack->touchedParam = NULL; | |||
| module->enableLearn(id); | |||
| e.consume(this); | |||
| } | |||
| @@ -276,9 +276,9 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||
| if (!module) | |||
| return; | |||
| // Check if a ParamWidget was touched | |||
| ParamWidget *touchedParam = APP->scene->rackWidget->touchedParam; | |||
| ParamWidget *touchedParam = APP->scene->rack->touchedParam; | |||
| if (touchedParam) { | |||
| APP->scene->rackWidget->touchedParam = NULL; | |||
| APP->scene->rack->touchedParam = NULL; | |||
| int moduleId = touchedParam->paramQuantity->module->id; | |||
| int paramId = touchedParam->paramQuantity->paramId; | |||
| module->learnParam(id, moduleId, paramId); | |||
| @@ -343,7 +343,7 @@ struct MIDI_MapChoice : LedDisplayChoice { | |||
| ParamHandle *paramHandle = &module->paramHandles[id]; | |||
| if (paramHandle->moduleId < 0) | |||
| return ""; | |||
| ModuleWidget *mw = APP->scene->rackWidget->getModule(paramHandle->moduleId); | |||
| ModuleWidget *mw = APP->scene->rack->getModule(paramHandle->moduleId); | |||
| if (!mw) | |||
| return ""; | |||
| // Get the Module from the ModuleWidget instead of the ParamHandle. | |||
| @@ -120,25 +120,25 @@ void CableWidget::setInput(PortWidget *inputPort) { | |||
| math::Vec CableWidget::getOutputPos() { | |||
| 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) { | |||
| return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), APP->scene->rackWidget); | |||
| return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), APP->scene->rack); | |||
| } | |||
| else { | |||
| return APP->scene->rackWidget->mousePos; | |||
| return APP->scene->rack->mousePos; | |||
| } | |||
| } | |||
| math::Vec CableWidget::getInputPos() { | |||
| 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) { | |||
| return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), APP->scene->rackWidget); | |||
| return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), APP->scene->rack); | |||
| } | |||
| 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"); | |||
| if (!outputModuleIdJ) return; | |||
| int outputModuleId = json_integer_value(outputModuleIdJ); | |||
| ModuleWidget *outputModule = APP->scene->rackWidget->getModule(outputModuleId); | |||
| ModuleWidget *outputModule = APP->scene->rack->getModule(outputModuleId); | |||
| if (!outputModule) return; | |||
| // inputModuleId | |||
| json_t *inputModuleIdJ = json_object_get(rootJ, "inputModuleId"); | |||
| if (!inputModuleIdJ) return; | |||
| int inputModuleId = json_integer_value(inputModuleIdJ); | |||
| ModuleWidget *inputModule = APP->scene->rackWidget->getModule(inputModuleId); | |||
| ModuleWidget *inputModule = APP->scene->rack->getModule(inputModuleId); | |||
| if (!inputModule) return; | |||
| // outputId | |||
| @@ -250,7 +250,7 @@ void CableWidget::drawPlugs(const DrawArgs &args) { | |||
| math::Vec inputPos = getInputPos(); | |||
| // 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); | |||
| if (isComplete()) { | |||
| // 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); | |||
| if (isComplete()) { | |||
| nvgSave(args.vg); | |||
| @@ -493,7 +493,7 @@ inline void ModelBox::onButton(const widget::ButtonEvent &e) { | |||
| // Create module | |||
| ModuleWidget *moduleWidget = model->createModuleWidget(); | |||
| 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 | |||
| e.consume(moduleWidget); | |||
| @@ -352,7 +352,7 @@ void ModuleWidget::onHoverKey(const widget::HoverKeyEvent &e) { | |||
| void ModuleWidget::onDragStart(const widget::DragStartEvent &e) { | |||
| oldPos = box.pos; | |||
| dragPos = APP->scene->rackWidget->mousePos.minus(box.pos); | |||
| dragPos = APP->scene->rack->mousePos.minus(box.pos); | |||
| e.consume(this); | |||
| } | |||
| @@ -370,8 +370,8 @@ void ModuleWidget::onDragEnd(const widget::DragEndEvent &e) { | |||
| void ModuleWidget::onDragMove(const widget::DragMoveEvent &e) { | |||
| if (!settings.lockModules) { | |||
| 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() { | |||
| for (PortWidget *input : inputs) { | |||
| APP->scene->rackWidget->clearCablesOnPort(input); | |||
| APP->scene->rack->clearCablesOnPort(input); | |||
| } | |||
| 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) { | |||
| // Add CableRemove action for all cables attached to 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()) | |||
| continue; | |||
| // history::CableRemove | |||
| @@ -686,7 +686,7 @@ static void disconnectActions(ModuleWidget *mw, history::ComplexAction *complexA | |||
| } | |||
| // Add CableRemove action for all cables attached to 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()) | |||
| continue; | |||
| // Avoid creating duplicate actions for self-patched cables | |||
| @@ -717,7 +717,7 @@ void ModuleWidget::cloneAction() { | |||
| clonedModuleWidget->fromJson(moduleJ); | |||
| json_decref(moduleJ); | |||
| APP->scene->rackWidget->addModuleAtMouse(clonedModuleWidget); | |||
| APP->scene->rack->addModuleAtMouse(clonedModuleWidget); | |||
| // history::ModuleAdd | |||
| history::ModuleAdd *h = new history::ModuleAdd; | |||
| @@ -749,7 +749,7 @@ void ModuleWidget::removeAction() { | |||
| APP->history->push(complexAction); | |||
| // This disconnects cables, removes the module, and transfers ownership to caller | |||
| APP->scene->rackWidget->removeModule(this); | |||
| APP->scene->rack->removeModule(this); | |||
| delete this; | |||
| } | |||
| @@ -150,7 +150,7 @@ void ParamWidget::onButton(const widget::ButtonEvent &e) { | |||
| // Touch parameter | |||
| if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == 0) { | |||
| if (paramQuantity) { | |||
| APP->scene->rackWidget->touchedParam = this; | |||
| APP->scene->rack->touchedParam = this; | |||
| } | |||
| } | |||
| @@ -30,7 +30,7 @@ PortWidget::~PortWidget() { | |||
| delete plugLight; | |||
| // HACK | |||
| if (module) | |||
| APP->scene->rackWidget->clearCablesOnPort(this); | |||
| APP->scene->rack->clearCablesOnPort(this); | |||
| } | |||
| void PortWidget::step() { | |||
| @@ -50,7 +50,7 @@ void PortWidget::step() { | |||
| } | |||
| void PortWidget::draw(const DrawArgs &args) { | |||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||
| if (cw) { | |||
| // Dim the PortWidget if the active cable cannot plug into this PortWidget | |||
| if (type == OUTPUT ? cw->outputPort : cw->inputPort) | |||
| @@ -61,14 +61,14 @@ void PortWidget::draw(const DrawArgs &args) { | |||
| void PortWidget::onButton(const widget::ButtonEvent &e) { | |||
| 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) { | |||
| // history::CableRemove | |||
| history::CableRemove *h = new history::CableRemove; | |||
| h->setCable(cw); | |||
| APP->history->push(h); | |||
| APP->scene->rackWidget->removeCable(cw); | |||
| APP->scene->rack->removeCable(cw); | |||
| delete cw; | |||
| } | |||
| } | |||
| @@ -91,7 +91,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||
| // Keep cable NULL. Will be created below | |||
| } | |||
| else { | |||
| CableWidget *topCw = APP->scene->rackWidget->getTopCable(this); | |||
| CableWidget *topCw = APP->scene->rack->getTopCable(this); | |||
| if (topCw) { | |||
| cw = new CableWidget; | |||
| cw->setOutput(topCw->outputPort); | |||
| @@ -100,7 +100,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||
| } | |||
| else { | |||
| // Grab cable on top of stack | |||
| cw = APP->scene->rackWidget->getTopCable(this); | |||
| cw = APP->scene->rack->getTopCable(this); | |||
| if (cw) { | |||
| // history::CableRemove | |||
| @@ -109,7 +109,7 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||
| APP->history->push(h); | |||
| // Disconnect and reuse existing cable | |||
| APP->scene->rackWidget->removeCable(cw); | |||
| APP->scene->rack->removeCable(cw); | |||
| if (type == OUTPUT) | |||
| cw->setOutput(NULL); | |||
| else | |||
| @@ -126,14 +126,14 @@ void PortWidget::onDragStart(const widget::DragStartEvent &e) { | |||
| cw->setInput(this); | |||
| } | |||
| APP->scene->rackWidget->setIncompleteCable(cw); | |||
| APP->scene->rack->setIncompleteCable(cw); | |||
| e.consume(this); | |||
| } | |||
| void PortWidget::onDragEnd(const widget::DragEndEvent &e) { | |||
| CableWidget *cw = APP->scene->rackWidget->releaseIncompleteCable(); | |||
| CableWidget *cw = APP->scene->rack->releaseIncompleteCable(); | |||
| if (cw->isComplete()) { | |||
| APP->scene->rackWidget->addCable(cw); | |||
| APP->scene->rack->addCable(cw); | |||
| // 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) { | |||
| // Reject ports if this is an input port and something is already plugged into it | |||
| if (type == INPUT) { | |||
| if (APP->scene->rackWidget->getTopCable(this)) | |||
| if (APP->scene->rack->getTopCable(this)) | |||
| return; | |||
| } | |||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||
| if (cw) { | |||
| cw->hoveredOutputPort = cw->hoveredInputPort = NULL; | |||
| if (type == OUTPUT) | |||
| @@ -165,11 +165,11 @@ void PortWidget::onDragDrop(const widget::DragDropEvent &e) { | |||
| void PortWidget::onDragEnter(const widget::DragEnterEvent &e) { | |||
| // Reject ports if this is an input port and something is already plugged into it | |||
| if (type == INPUT) { | |||
| if (APP->scene->rackWidget->getTopCable(this)) | |||
| if (APP->scene->rack->getTopCable(this)) | |||
| return; | |||
| } | |||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||
| if (cw) { | |||
| if (type == OUTPUT) | |||
| cw->hoveredOutputPort = this; | |||
| @@ -184,7 +184,7 @@ void PortWidget::onDragLeave(const widget::DragLeaveEvent &e) { | |||
| if (!originPort) | |||
| return; | |||
| CableWidget *cw = APP->scene->rackWidget->incompleteCable; | |||
| CableWidget *cw = APP->scene->rack->incompleteCable; | |||
| if (cw) { | |||
| if (type == OUTPUT) | |||
| cw->hoveredOutputPort = NULL; | |||
| @@ -2,17 +2,41 @@ | |||
| #include "app/Scene.hpp" | |||
| #include "window.hpp" | |||
| #include "app.hpp" | |||
| #include "settings.hpp" | |||
| namespace rack { | |||
| namespace app { | |||
| RackScrollWidget::RackScrollWidget() { | |||
| zoom = new widget::ZoomWidget; | |||
| container->addChild(zoom); | |||
| rack = new RackWidget; | |||
| zoom->addChild(rack); | |||
| } | |||
| 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::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 speed = 15.0; | |||
| if (pos.x <= viewport.pos.x + margin) | |||
| @@ -24,6 +48,7 @@ void RackScrollWidget::step() { | |||
| if (pos.y >= viewport.pos.y + viewport.size.y - margin) | |||
| offset.y += speed; | |||
| } | |||
| ScrollWidget::step(); | |||
| } | |||
| @@ -32,6 +57,43 @@ void RackScrollWidget::draw(const DrawArgs &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 rack | |||
| @@ -122,37 +122,12 @@ void RackWidget::draw(const DrawArgs &args) { | |||
| } | |||
| 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; | |||
| OpaqueWidget::onHover(e); | |||
| } | |||
| void RackWidget::onHoverKey(const widget::HoverKeyEvent &e) { | |||
| widget::OpaqueWidget::onHoverKey(e); | |||
| OpaqueWidget::onHoverKey(e); | |||
| if (e.getConsumed() != this) | |||
| return; | |||
| @@ -168,12 +143,12 @@ void RackWidget::onHoverKey(const widget::HoverKeyEvent &e) { | |||
| } | |||
| void RackWidget::onDragHover(const widget::DragHoverEvent &e) { | |||
| widget::OpaqueWidget::onDragHover(e); | |||
| OpaqueWidget::onDragHover(e); | |||
| mousePos = e.pos; | |||
| } | |||
| void RackWidget::onButton(const widget::ButtonEvent &e) { | |||
| widget::OpaqueWidget::onButton(e); | |||
| OpaqueWidget::onButton(e); | |||
| if (e.getConsumed() == this) { | |||
| if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { | |||
| APP->scene->moduleBrowser->show(); | |||
| @@ -183,7 +158,7 @@ void RackWidget::onButton(const widget::ButtonEvent &e) { | |||
| void RackWidget::onZoom(const widget::ZoomEvent &e) { | |||
| rails->box.size = math::Vec(); | |||
| widget::OpaqueWidget::onZoom(e); | |||
| OpaqueWidget::onZoom(e); | |||
| } | |||
| void RackWidget::clear() { | |||
| @@ -1,9 +1,8 @@ | |||
| #include "system.hpp" | |||
| #include "network.hpp" | |||
| #include "app/Scene.hpp" | |||
| #include "app/ModuleBrowser.hpp" | |||
| #include "app/RackScrollWidget.hpp" | |||
| #include "app.hpp" | |||
| #include "system.hpp" | |||
| #include "network.hpp" | |||
| #include "history.hpp" | |||
| #include "settings.hpp" | |||
| #include "patch.hpp" | |||
| @@ -17,23 +16,17 @@ namespace app { | |||
| 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; | |||
| addChild(toolbar); | |||
| scrollWidget->box.pos.y = toolbar->box.size.y; | |||
| rackScroll->box.pos.y = toolbar->box.size.y; | |||
| moduleBrowser = moduleBrowserCreate(); | |||
| moduleBrowser->visible = false; | |||
| moduleBrowser->hide(); | |||
| addChild(moduleBrowser); | |||
| } | |||
| @@ -43,17 +36,7 @@ Scene::~Scene() { | |||
| void Scene::step() { | |||
| // Resize owned descendants | |||
| 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 | |||
| double time = glfwGetTime(); | |||
| @@ -63,11 +46,6 @@ void Scene::step() { | |||
| 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 | |||
| if (!devMode && checkVersion && !checkedVersion) { | |||
| std::thread t(&Scene::runCheckVersion, this); | |||
| @@ -85,6 +63,8 @@ void Scene::step() { | |||
| } | |||
| latestVersion = ""; | |||
| } | |||
| OpaqueWidget::step(); | |||
| } | |||
| void Scene::draw(const DrawArgs &args) { | |||
| @@ -48,9 +48,9 @@ void ModuleAdd::setModule(app::ModuleWidget *mw) { | |||
| } | |||
| void ModuleAdd::undo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| APP->scene->rackWidget->removeModule(mw); | |||
| APP->scene->rack->removeModule(mw); | |||
| delete mw; | |||
| } | |||
| @@ -61,31 +61,31 @@ void ModuleAdd::redo() { | |||
| mw->module->id = moduleId; | |||
| mw->box.pos = pos; | |||
| mw->fromJson(moduleJ); | |||
| APP->scene->rackWidget->addModule(mw); | |||
| APP->scene->rack->addModule(mw); | |||
| } | |||
| void ModuleMove::undo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->box.pos = oldPos; | |||
| } | |||
| void ModuleMove::redo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->box.pos = newPos; | |||
| } | |||
| void ModuleBypass::undo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| APP->engine->bypassModule(mw->module, !bypass); | |||
| } | |||
| void ModuleBypass::redo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| APP->engine->bypassModule(mw->module, bypass); | |||
| } | |||
| @@ -97,26 +97,26 @@ ModuleChange::~ModuleChange() { | |||
| } | |||
| void ModuleChange::undo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->fromJson(oldModuleJ); | |||
| } | |||
| void ModuleChange::redo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->fromJson(newModuleJ); | |||
| } | |||
| void ParamChange::undo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->module->params[paramId].value = oldValue; | |||
| } | |||
| void ParamChange::redo() { | |||
| app::ModuleWidget *mw = APP->scene->rackWidget->getModule(moduleId); | |||
| app::ModuleWidget *mw = APP->scene->rack->getModule(moduleId); | |||
| assert(mw); | |||
| mw->module->params[paramId].value = newValue; | |||
| } | |||
| @@ -136,8 +136,8 @@ void CableAdd::setCable(app::CableWidget *cw) { | |||
| } | |||
| 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; | |||
| } | |||
| @@ -145,13 +145,13 @@ void CableAdd::redo() { | |||
| app::CableWidget *cw = new app::CableWidget; | |||
| cw->cable->id = cableId; | |||
| app::ModuleWidget *outputModule = APP->scene->rackWidget->getModule(outputModuleId); | |||
| app::ModuleWidget *outputModule = APP->scene->rack->getModule(outputModuleId); | |||
| assert(outputModule); | |||
| app::PortWidget *outputPort = outputModule->getOutput(outputId); | |||
| assert(outputPort); | |||
| cw->setOutput(outputPort); | |||
| app::ModuleWidget *inputModule = APP->scene->rackWidget->getModule(inputModuleId); | |||
| app::ModuleWidget *inputModule = APP->scene->rack->getModule(inputModuleId); | |||
| assert(inputModule); | |||
| app::PortWidget *inputPort = inputModule->getInput(inputId); | |||
| assert(inputPort); | |||
| @@ -159,7 +159,7 @@ void CableAdd::redo() { | |||
| 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() { | |||
| 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 | |||
| load(asset::user("template.vcv")); | |||
| legacy = 0; | |||
| @@ -168,8 +168,8 @@ bool PatchManager::load(std::string path) { | |||
| }); | |||
| 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); | |||
| return true; | |||
| } | |||
| @@ -215,7 +215,7 @@ void PatchManager::disconnectDialog() { | |||
| // if (!osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK_CANCEL, "Remove all patch cables?")) | |||
| // return; | |||
| APP->scene->rackWidget->clearCablesAction(); | |||
| APP->scene->rack->clearCablesAction(); | |||
| } | |||
| json_t *PatchManager::toJson() { | |||
| @@ -227,7 +227,7 @@ json_t *PatchManager::toJson() { | |||
| json_object_set_new(rootJ, "version", versionJ); | |||
| // Merge with RackWidget JSON | |||
| json_t *rackJ = APP->scene->rackWidget->toJson(); | |||
| json_t *rackJ = APP->scene->rack->toJson(); | |||
| // Merge with rootJ | |||
| json_object_update(rootJ, rackJ); | |||
| json_decref(rackJ); | |||
| @@ -259,7 +259,7 @@ void PatchManager::fromJson(json_t *rootJ) { | |||
| 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 | |||
| if (!warningLog.empty()) { | |||