@@ -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()) { | ||||