From 655f081965a337e75517b05fa6051004abe3b90f Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 7 Jan 2019 20:09:28 -0500 Subject: [PATCH] Rename context() to app(). Add skeleton for history. --- include/{context.hpp => app.hpp} | 14 ++++++-- include/app/Knob.hpp | 2 +- include/app/SVGPanel.hpp | 4 +-- include/helpers.hpp | 6 ++-- include/history.hpp | 25 +++++++++++++ include/rack.hpp | 2 +- include/rack0.hpp | 8 ++--- include/ui/MenuItem.hpp | 2 +- include/ui/MenuLabel.hpp | 6 ++-- include/ui/Slider.hpp | 6 ++-- include/ui/TextField.hpp | 2 +- include/window.hpp | 2 ++ src/Core/AudioInterface.cpp | 4 +-- src/Core/Blank.cpp | 8 ++--- src/Core/MIDICCToCVInterface.cpp | 10 +++--- src/Core/MIDIToCVInterface.cpp | 2 +- src/Core/MIDITriggerToCVInterface.cpp | 6 ++-- src/app.cpp | 48 +++++++++++++++++++++++++ src/app/Knob.cpp | 6 ++-- src/app/LedDisplay.cpp | 10 +++--- src/app/ModuleBrowser.cpp | 38 ++++++++++++-------- src/app/ModuleWidget.cpp | 52 +++++++++++++-------------- src/app/ParamWidget.cpp | 10 +++--- src/app/PortWidget.cpp | 22 ++++++------ src/app/RackScrollWidget.cpp | 6 ++-- src/app/RackWidget.cpp | 10 +++--- src/app/Scene.cpp | 33 +++++++++++------ src/app/Toolbar.cpp | 34 +++++++++--------- src/app/WireWidget.cpp | 22 ++++++------ src/context.cpp | 15 -------- src/engine/Light.cpp | 4 +-- src/history.cpp | 22 ++++++++++++ src/main.cpp | 39 ++++++++------------ src/plugin.cpp | 2 +- src/settings.cpp | 24 ++++++------- src/ui/MenuItem.cpp | 8 ++--- src/ui/ScrollBar.cpp | 6 ++-- src/ui/ScrollWidget.cpp | 18 +++++----- src/ui/TextField.cpp | 30 ++++++++-------- src/ui/Tooltip.cpp | 6 ++-- src/widgets/FramebufferWidget.cpp | 12 +++---- src/widgets/Widget.cpp | 10 +++--- src/window.cpp | 34 +++++++++--------- 43 files changed, 365 insertions(+), 265 deletions(-) rename include/{context.hpp => app.hpp} (69%) create mode 100644 include/history.hpp create mode 100644 src/app.cpp delete mode 100644 src/context.cpp create mode 100644 src/history.cpp diff --git a/include/context.hpp b/include/app.hpp similarity index 69% rename from include/context.hpp rename to include/app.hpp index 37d81842..aa3b0f0a 100644 --- a/include/context.hpp +++ b/include/app.hpp @@ -9,22 +9,32 @@ namespace event { struct State; } +namespace history { + struct State; +} + struct Scene; struct Engine; struct Window; /** Contains the application state */ -struct Context { +struct App { event::State *event = NULL; Scene *scene = NULL; Engine *engine = NULL; Window *window = NULL; + history::State *history = NULL; + + App(); + ~App(); }; +void appInit(); +void appDestroy(); /** Returns the global context */ -Context *context(); +App *app(); } // namespace rack diff --git a/include/app/Knob.hpp b/include/app/Knob.hpp index 9e9111c5..4d292a81 100644 --- a/include/app/Knob.hpp +++ b/include/app/Knob.hpp @@ -1,7 +1,7 @@ #pragma once #include "app/common.hpp" #include "app/ParamWidget.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { diff --git a/include/app/SVGPanel.hpp b/include/app/SVGPanel.hpp index 86407792..d13914d5 100644 --- a/include/app/SVGPanel.hpp +++ b/include/app/SVGPanel.hpp @@ -3,7 +3,7 @@ #include "widgets/TransparentWidget.hpp" #include "widgets/FramebufferWidget.hpp" #include "widgets/SVGWidget.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -23,7 +23,7 @@ struct PanelBorder : TransparentWidget { struct SVGPanel : FramebufferWidget { void step() override { - if (math::isNear(context()->window->pixelRatio, 1.0)) { + if (math::isNear(app()->window->pixelRatio, 1.0)) { // Small details draw poorly at low DPI, so oversample when drawing to the framebuffer oversample = 2.0; } diff --git a/include/helpers.hpp b/include/helpers.hpp index 8375cf93..320f90d6 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -7,7 +7,7 @@ #include "app/ParamWidget.hpp" #include "app/Scene.hpp" #include "engine/Module.hpp" -#include "context.hpp" +#include "app.hpp" #include "window.hpp" @@ -150,12 +150,12 @@ TMenuItem *createMenuItem(std::string text, std::string rightText = "") { inline Menu *createMenu() { Menu *o = new Menu; - o->box.pos = context()->window->mousePos; + o->box.pos = app()->window->mousePos; MenuOverlay *menuOverlay = new MenuOverlay; menuOverlay->addChild(o); - context()->scene->addChild(menuOverlay); + app()->scene->addChild(menuOverlay); return o; } diff --git a/include/history.hpp b/include/history.hpp new file mode 100644 index 00000000..968d6d03 --- /dev/null +++ b/include/history.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "common.hpp" + + +namespace rack { +namespace history { + + +struct Action { + virtual ~Action() {} + virtual void commit() {} + virtual void commitInverse() {} +}; + + + +struct State { + void push(Action *action); + void undo(); + void redo(); +}; + + +} // namespace history +} // namespace rack diff --git a/include/rack.hpp b/include/rack.hpp index 7e944204..e9113bd9 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -8,7 +8,7 @@ #include "network.hpp" #include "asset.hpp" #include "window.hpp" -#include "context.hpp" +#include "app.hpp" #include "helpers.hpp" #include "widgets/Widget.hpp" diff --git a/include/rack0.hpp b/include/rack0.hpp index 1e312f8c..c4aa3a05 100644 --- a/include/rack0.hpp +++ b/include/rack0.hpp @@ -140,11 +140,11 @@ DEPRECATED TPortWidget *createPort(math::Vec pos, PortWidget::Type type, Module //////////////////// DEPRECATED inline float engineGetSampleRate() { - return context()->engine->getSampleRate(); + return app()->engine->getSampleRate(); } DEPRECATED inline float engineGetSampleTime() { - return context()->engine->getSampleTime(); + return app()->engine->getSampleTime(); } //////////////////// @@ -153,11 +153,11 @@ DEPRECATED inline float engineGetSampleTime() { using namespace dsp; -inline float gainToDb(float gain) { +DEPRECATED inline float gainToDb(float gain) { return dsp::amplitudeToDb(gain); } -inline float dbToGain(float db) { +DEPRECATED inline float dbToGain(float db) { return dsp::dbToAmplitude(db); } diff --git a/include/ui/MenuItem.hpp b/include/ui/MenuItem.hpp index 532b4bb3..c1bc13c3 100644 --- a/include/ui/MenuItem.hpp +++ b/include/ui/MenuItem.hpp @@ -3,7 +3,7 @@ #include "ui/Menu.hpp" #include "ui/MenuEntry.hpp" #include "ui/MenuOverlay.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { diff --git a/include/ui/MenuLabel.hpp b/include/ui/MenuLabel.hpp index 9ad84e6a..b1618cb4 100644 --- a/include/ui/MenuLabel.hpp +++ b/include/ui/MenuLabel.hpp @@ -1,7 +1,7 @@ #pragma once #include "ui/common.hpp" #include "ui/MenuEntry.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -17,8 +17,8 @@ struct MenuLabel : MenuEntry { void step() override { // Add 10 more pixels because Retina measurements are sometimes too small const float rightPadding = 10.0; - // HACK use context()->window->vg from the window. - box.size.x = bndLabelWidth(context()->window->vg, -1, text.c_str()) + rightPadding; + // HACK use app()->window->vg from the window. + box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()) + rightPadding; Widget::step(); } }; diff --git a/include/ui/Slider.hpp b/include/ui/Slider.hpp index 50d923be..0b99c290 100644 --- a/include/ui/Slider.hpp +++ b/include/ui/Slider.hpp @@ -2,7 +2,7 @@ #include "widgets/OpaqueWidget.hpp" #include "ui/Quantity.hpp" #include "ui/common.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -32,7 +32,7 @@ struct Slider : OpaqueWidget { void onDragStart(const event::DragStart &e) override { state = BND_ACTIVE; - context()->window->cursorLock(); + app()->window->cursorLock(); } void onDragMove(const event::DragMove &e) override { @@ -43,7 +43,7 @@ struct Slider : OpaqueWidget { void onDragEnd(const event::DragEnd &e) override { state = BND_DEFAULT; - context()->window->cursorUnlock(); + app()->window->cursorUnlock(); } void onButton(const event::Button &e) override { diff --git a/include/ui/TextField.hpp b/include/ui/TextField.hpp index c1bcae8f..a6086570 100644 --- a/include/ui/TextField.hpp +++ b/include/ui/TextField.hpp @@ -2,7 +2,7 @@ #include "widgets/OpaqueWidget.hpp" #include "ui/common.hpp" #include "event.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { diff --git a/include/window.hpp b/include/window.hpp index 101636d3..0186820e 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -11,8 +11,10 @@ #ifdef ARCH_MAC + #define WINDOW_MOD GLFW_MOD_SUPER #define WINDOW_MOD_KEY_NAME "Cmd" #else + #define WINDOW_MOD GLFW_MOD_CONTROL #define WINDOW_MOD_KEY_NAME "Ctrl" #endif diff --git a/src/Core/AudioInterface.cpp b/src/Core/AudioInterface.cpp index 325f6b41..155197de 100644 --- a/src/Core/AudioInterface.cpp +++ b/src/Core/AudioInterface.cpp @@ -5,7 +5,7 @@ #include #include #include -#include "context.hpp" +#include "app.hpp" #define AUDIO_OUTPUTS 8 @@ -143,7 +143,7 @@ struct AudioInterface : Module { void AudioInterface::step() { // Update SRC states - int sampleRate = (int) context()->engine->getSampleRate(); + int sampleRate = (int) app()->engine->getSampleRate(); inputSrc.setRates(audioIO.sampleRate, sampleRate); outputSrc.setRates(sampleRate, audioIO.sampleRate); diff --git a/src/Core/Blank.cpp b/src/Core/Blank.cpp index bdb3bb95..e9b288f6 100644 --- a/src/Core/Blank.cpp +++ b/src/Core/Blank.cpp @@ -1,5 +1,5 @@ #include "Core.hpp" -#include "context.hpp" +#include "app.hpp" using namespace rack; @@ -39,14 +39,14 @@ struct ModuleResizeHandle : virtual Widget { } } void onDragStart(const event::DragStart &e) override { - dragX = context()->scene->rackWidget->lastMousePos.x; + dragX = app()->scene->rackWidget->lastMousePos.x; ModuleWidget *m = getAncestorOfType(); originalBox = m->box; } void onDragMove(const event::DragMove &e) override { ModuleWidget *m = getAncestorOfType(); - float newDragX = context()->scene->rackWidget->lastMousePos.x; + float newDragX = app()->scene->rackWidget->lastMousePos.x; float deltaX = newDragX - dragX; Rect newBox = originalBox; @@ -62,7 +62,7 @@ struct ModuleResizeHandle : virtual 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; } - context()->scene->rackWidget->requestModuleBox(m, newBox); + app()->scene->rackWidget->requestModuleBox(m, newBox); } void draw(NVGcontext *vg) override { for (float x = 5.0; x <= 10.0; x += 5.0) { diff --git a/src/Core/MIDICCToCVInterface.cpp b/src/Core/MIDICCToCVInterface.cpp index ab295705..73d9e1ea 100644 --- a/src/Core/MIDICCToCVInterface.cpp +++ b/src/Core/MIDICCToCVInterface.cpp @@ -45,7 +45,7 @@ struct MIDICCToCVInterface : Module { processMessage(msg); } - float lambda = 100.f * context()->engine->getSampleTime(); + float lambda = 100.f * app()->engine->getSampleTime(); for (int i = 0; i < 16; i++) { int learnedCc = learnedCcs[i]; float value = rescale(clamp(ccs[learnedCc], -127, 127), 0, 127, 0.f, 10.f); @@ -132,8 +132,8 @@ struct MidiCcChoice : GridChoice { else { text = string::f("%d", module->learnedCcs[id]); color.a = 1.0; - if (context()->event->selectedWidget == this) - context()->event->selectedWidget = NULL; + if (app()->event->selectedWidget == this) + app()->event->selectedWidget = NULL; } } @@ -165,11 +165,11 @@ struct MidiCcChoice : GridChoice { } void onSelectKey(const event::SelectKey &e) override { - if (context()->event->selectedWidget == this) { + if (app()->event->selectedWidget == this) { if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) { event::Deselect eDeselect; onDeselect(eDeselect); - context()->event->selectedWidget = NULL; + app()->event->selectedWidget = NULL; e.consume(this); } } diff --git a/src/Core/MIDIToCVInterface.cpp b/src/Core/MIDIToCVInterface.cpp index 77e7d725..6f9e0fd7 100644 --- a/src/Core/MIDIToCVInterface.cpp +++ b/src/Core/MIDIToCVInterface.cpp @@ -144,7 +144,7 @@ struct MIDIToCVInterface : Module { while (midiInput.shift(&msg)) { processMessage(msg); } - float deltaTime = context()->engine->getSampleTime(); + float deltaTime = app()->engine->getSampleTime(); outputs[CV_OUTPUT].setVoltage((lastNote - 60) / 12.f); outputs[GATE_OUTPUT].setVoltage(gate ? 10.f : 0.f); diff --git a/src/Core/MIDITriggerToCVInterface.cpp b/src/Core/MIDITriggerToCVInterface.cpp index 6ee7dc9d..a2932eb1 100644 --- a/src/Core/MIDITriggerToCVInterface.cpp +++ b/src/Core/MIDITriggerToCVInterface.cpp @@ -71,7 +71,7 @@ struct MIDITriggerToCVInterface : Module { while (midiInput.shift(&msg)) { processMessage(msg); } - float deltaTime = context()->engine->getSampleTime(); + float deltaTime = app()->engine->getSampleTime(); for (int i = 0; i < 16; i++) { if (gateTimes[i] > 0.f) { @@ -175,8 +175,8 @@ struct MidiTrigChoice : GridChoice { text = string::f("%s%d", noteNames[semi], oct); color.a = 1.0; - if (context()->event->selectedWidget == this) - context()->event->selectedWidget = NULL; + if (app()->event->selectedWidget == this) + app()->event->selectedWidget = NULL; } } diff --git a/src/app.cpp b/src/app.cpp new file mode 100644 index 00000000..ee135ca5 --- /dev/null +++ b/src/app.cpp @@ -0,0 +1,48 @@ +#include "app.hpp" +#include "event.hpp" +#include "window.hpp" +#include "engine/Engine.hpp" +#include "app/Scene.hpp" +#include "history.hpp" + + +namespace rack { + + +App::App() { + event = new event::State; + history = new history::State; + window = new Window; + engine = new Engine; + scene = new Scene; + event->rootWidget = scene; +} + +App::~App() { + delete scene; scene = NULL; + delete event; event = NULL; + delete history; history = NULL; + delete engine; engine = NULL; + delete window; window = NULL; +} + + +static App *c = NULL; + +void appInit() { + assert(!c); + c = new App; +} + +void appDestroy() { + assert(c); + delete c; + c = NULL; +} + +App *app() { + return c; +} + + +} // namespace rack diff --git a/src/app/Knob.cpp b/src/app/Knob.cpp index bf3033de..73476c01 100644 --- a/src/app/Knob.cpp +++ b/src/app/Knob.cpp @@ -17,11 +17,11 @@ void Knob::onButton(const event::Button &e) { } void Knob::onDragStart(const event::DragStart &e) { - context()->window->cursorLock(); + app()->window->cursorLock(); } void Knob::onDragEnd(const event::DragEnd &e) { - context()->window->cursorUnlock(); + app()->window->cursorUnlock(); } void Knob::onDragMove(const event::DragMove &e) { @@ -37,7 +37,7 @@ void Knob::onDragMove(const event::DragMove &e) { float delta = KNOB_SENSITIVITY * -e.mouseDelta.y * speed * range; // Drag slower if Mod is held - if (context()->window->isModPressed()) + if (app()->window->isModPressed()) delta /= 16.f; quantity->moveValue(delta); } diff --git a/src/app/LedDisplay.cpp b/src/app/LedDisplay.cpp index 62754095..c83e8b7e 100644 --- a/src/app/LedDisplay.cpp +++ b/src/app/LedDisplay.cpp @@ -2,7 +2,7 @@ #include "asset.hpp" #include "window.hpp" #include "event.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -86,12 +86,12 @@ void LedDisplayTextField::draw(NVGcontext *vg) { NVGcolor highlightColor = color; highlightColor.a = 0.5; int begin = std::min(cursor, selection); - int end = (this == context()->event->selectedWidget) ? std::max(cursor, selection) : -1; + int end = (this == app()->event->selectedWidget) ? std::max(cursor, selection) : -1; bndIconLabelCaret(vg, textOffset.x, textOffset.y, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, color, 12, text.c_str(), highlightColor, begin, end); - bndSetFont(context()->window->uiFont->handle); + bndSetFont(app()->window->uiFont->handle); } nvgResetScissor(vg); @@ -99,10 +99,10 @@ void LedDisplayTextField::draw(NVGcontext *vg) { int LedDisplayTextField::getTextPosition(math::Vec mousePos) { bndSetFont(font->handle); - int textPos = bndIconLabelTextPosition(context()->window->vg, textOffset.x, textOffset.y, + int textPos = bndIconLabelTextPosition(app()->window->vg, textOffset.x, textOffset.y, box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y, -1, 12, text.c_str(), mousePos.x, mousePos.y); - bndSetFont(context()->window->uiFont->handle); + bndSetFont(app()->window->uiFont->handle); return textPos; } diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index 92d85c44..2713f9b8 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -7,7 +7,7 @@ #include "app/ModuleWidget.hpp" #include "app/Scene.hpp" #include "plugin.hpp" -#include "context.hpp" +#include "app.hpp" #include #include @@ -21,26 +21,17 @@ static std::set sFavoriteModels; struct ModuleBox : OpaqueWidget { Model *model; + bool initialized = false; void setModel(Model *model) { this->model = model; - Widget *transparentWidget = new TransparentWidget; - addChild(transparentWidget); - - ZoomWidget *zoomWidget = new ZoomWidget; - zoomWidget->setZoom(0.5); - transparentWidget->addChild(zoomWidget); - - ModuleWidget *moduleWidget = model->createModuleWidgetNull(); - zoomWidget->addChild(moduleWidget); - - box.size = math::Vec(moduleWidget->box.size.x, RACK_GRID_SIZE.y).mult(zoomWidget->zoom).ceil(); + box.size.x = 70.f; + box.size.y = std::ceil(RACK_GRID_SIZE.y * 0.5f); math::Vec p; p.y = box.size.y; box.size.y += 40.0; - box.size.x = std::max(box.size.x, 70.f); Label *nameLabel = new Label; nameLabel->text = model->name; @@ -56,8 +47,25 @@ struct ModuleBox : OpaqueWidget { } void draw(NVGcontext *vg) override { + // Lazily create ModuleWidget when drawn + if (!initialized) { + Widget *transparentWidget = new TransparentWidget; + addChild(transparentWidget); + + ZoomWidget *zoomWidget = new ZoomWidget; + zoomWidget->setZoom(0.5f); + transparentWidget->addChild(zoomWidget); + + ModuleWidget *moduleWidget = model->createModuleWidgetNull(); + zoomWidget->addChild(moduleWidget); + + float width = std::ceil(moduleWidget->box.size.x * 0.5f); + box.size.x = std::max(box.size.x, width); + initialized = true; + } + OpaqueWidget::draw(vg); - if (context()->event->hoveredWidget == this) { + if (app()->event->hoveredWidget == this) { nvgBeginPath(vg); nvgRect(vg, 0.0, 0.0, box.size.x, box.size.y); nvgFillColor(vg, nvgRGBAf(1, 1, 1, 0.25)); @@ -70,7 +78,7 @@ struct ModuleBox : OpaqueWidget { // Create module ModuleWidget *moduleWidget = model->createModuleWidget(); assert(moduleWidget); - context()->scene->rackWidget->addModule(moduleWidget); + app()->scene->rackWidget->addModule(moduleWidget); // This is a bit nonstandard/unsupported usage, but pretend the moduleWidget was clicked so it can be dragged in the RackWidget e.consume(moduleWidget); // Close Module Browser diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index b85700df..2bb9b9be 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -5,7 +5,7 @@ #include "app/Scene.hpp" #include "app/SVGPanel.hpp" #include "helpers.hpp" -#include "context.hpp" +#include "app.hpp" #include "settings.hpp" #include "osdialog.h" @@ -16,20 +16,20 @@ namespace rack { ModuleWidget::ModuleWidget(Module *module) { if (module) { - context()->engine->addModule(module); + app()->engine->addModule(module); } this->module = module; } ModuleWidget::~ModuleWidget() { // HACK - // If we try to disconnect wires in the Module Browser (e.g. when Rack is closed while the Module Browser is open), context()->scene->rackWidget will be an invalid pointer. + // If we try to disconnect wires in the Module Browser (e.g. when Rack is closed while the Module Browser is open), app()->scene->rackWidget will be an invalid pointer. // So only attempt to disconnect if the module is not NULL. if (module) disconnect(); // Remove and delete the Module instance if (module) { - context()->engine->removeModule(module); + app()->engine->removeModule(module); delete module; module = NULL; } @@ -136,11 +136,11 @@ void ModuleWidget::copyClipboard() { DEFER({ free(moduleJson); }); - glfwSetClipboardString(context()->window->win, moduleJson); + glfwSetClipboardString(app()->window->win, moduleJson); } void ModuleWidget::pasteClipboard() { - const char *moduleJson = glfwGetClipboardString(context()->window->win); + const char *moduleJson = glfwGetClipboardString(app()->window->win); if (!moduleJson) { WARN("Could not get text from clipboard."); return; @@ -261,22 +261,22 @@ void ModuleWidget::toggleBypass() { void ModuleWidget::disconnect() { for (PortWidget *input : inputs) { - context()->scene->rackWidget->wireContainer->removeAllWires(input); + app()->scene->rackWidget->wireContainer->removeAllWires(input); } for (PortWidget *output : outputs) { - context()->scene->rackWidget->wireContainer->removeAllWires(output); + app()->scene->rackWidget->wireContainer->removeAllWires(output); } } void ModuleWidget::reset() { if (module) { - context()->engine->resetModule(module); + app()->engine->resetModule(module); } } void ModuleWidget::randomize() { if (module) { - context()->engine->randomizeModule(module); + app()->engine->randomizeModule(module); } } @@ -298,7 +298,7 @@ void ModuleWidget::draw(NVGcontext *vg) { std::string cpuText = string::f("%.0f mS", module->cpuTime * 1000.f); // TODO Use blendish text function - nvgFontFaceId(vg, context()->window->uiFont->handle); + nvgFontFaceId(vg, app()->window->uiFont->handle); nvgFontSize(vg, 12); nvgFillColor(vg, nvgRGBf(1, 1, 1)); nvgText(vg, 10.0, box.size.y - 6.0, cpuText.c_str(), NULL); @@ -331,8 +331,8 @@ void ModuleWidget::onHover(const event::Hover &e) { OpaqueWidget::onHover(e); // Instead of checking key-down events, delete the module even if key-repeat hasn't fired yet and the cursor is hovering over the widget. - if (glfwGetKey(context()->window->win, GLFW_KEY_DELETE) == GLFW_PRESS || glfwGetKey(context()->window->win, GLFW_KEY_BACKSPACE) == GLFW_PRESS) { - if (!context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (glfwGetKey(app()->window->win, GLFW_KEY_DELETE) == GLFW_PRESS || glfwGetKey(app()->window->win, GLFW_KEY_BACKSPACE) == GLFW_PRESS) { + if (!app()->window->isModPressed() && !app()->window->isShiftPressed()) { requestedDelete = true; return; } @@ -352,43 +352,43 @@ void ModuleWidget::onHoverKey(const event::HoverKey &e) { if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { switch (e.key) { case GLFW_KEY_I: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { reset(); e.consume(this); } } break; case GLFW_KEY_R: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { randomize(); e.consume(this); } } break; case GLFW_KEY_C: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { copyClipboard(); e.consume(this); } } break; case GLFW_KEY_V: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { pasteClipboard(); e.consume(this); } } break; case GLFW_KEY_D: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { - context()->scene->rackWidget->cloneModule(this); + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { + app()->scene->rackWidget->cloneModule(this); e.consume(this); } } break; case GLFW_KEY_U: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { disconnect(); e.consume(this); } } break; case GLFW_KEY_E: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if (app()->window->isModPressed() && !app()->window->isShiftPressed()) { toggleBypass(); e.consume(this); } @@ -401,7 +401,7 @@ void ModuleWidget::onHoverKey(const event::HoverKey &e) { } void ModuleWidget::onDragStart(const event::DragStart &e) { - dragPos = context()->scene->rackWidget->lastMousePos.minus(box.pos); + dragPos = app()->scene->rackWidget->lastMousePos.minus(box.pos); } void ModuleWidget::onDragEnd(const event::DragEnd &e) { @@ -410,8 +410,8 @@ void ModuleWidget::onDragEnd(const event::DragEnd &e) { void ModuleWidget::onDragMove(const event::DragMove &e) { if (!settings::lockModules) { math::Rect newBox = box; - newBox.pos = context()->scene->rackWidget->lastMousePos.minus(dragPos); - context()->scene->rackWidget->requestModuleBoxNearest(this, newBox); + newBox.pos = app()->scene->rackWidget->lastMousePos.minus(dragPos); + app()->scene->rackWidget->requestModuleBoxNearest(this, newBox); } } @@ -498,7 +498,7 @@ struct ModuleCloneItem : MenuItem { rightText = WINDOW_MOD_KEY_NAME "+D"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->cloneModule(moduleWidget); + app()->scene->rackWidget->cloneModule(moduleWidget); } }; @@ -526,7 +526,7 @@ struct ModuleDeleteItem : MenuItem { rightText = "Backspace/Delete"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->deleteModule(moduleWidget); + app()->scene->rackWidget->deleteModule(moduleWidget); delete moduleWidget; } }; diff --git a/src/app/ParamWidget.cpp b/src/app/ParamWidget.cpp index e7c62c85..e15dc5be 100644 --- a/src/app/ParamWidget.cpp +++ b/src/app/ParamWidget.cpp @@ -3,7 +3,7 @@ #include "ui/TextField.hpp" #include "app/Scene.hpp" #include "app/ParamQuantity.hpp" -#include "context.hpp" +#include "app.hpp" #include "settings.hpp" #include "random.hpp" @@ -16,7 +16,7 @@ struct ParamField : TextField { void step() override { // Keep selected - context()->event->setSelected(this); + app()->event->setSelected(this); } void setParamWidget(ParamWidget *paramWidget) { @@ -104,7 +104,7 @@ void ParamWidget::onButton(const event::Button &e) { if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & GLFW_MOD_SHIFT) && !(e.mods & GLFW_MOD_CONTROL)) { // Create ParamField MenuOverlay *overlay = new MenuOverlay; - context()->scene->addChild(overlay); + app()->scene->addChild(overlay); ParamField *paramField = new ParamField; paramField->box.size.x = 100; @@ -119,13 +119,13 @@ void ParamWidget::onButton(const event::Button &e) { void ParamWidget::onEnter(const event::Enter &e) { if (settings::paramTooltip && !tooltip) { tooltip = new Tooltip; - context()->scene->addChild(tooltip); + app()->scene->addChild(tooltip); } } void ParamWidget::onLeave(const event::Leave &e) { if (tooltip) { - context()->scene->removeChild(tooltip); + app()->scene->removeChild(tooltip); delete tooltip; tooltip = NULL; } diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index d266a847..e5447970 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -1,7 +1,7 @@ #include "app/PortWidget.hpp" #include "app/Scene.hpp" #include "window.hpp" -#include "context.hpp" +#include "app.hpp" #include "componentlibrary.hpp" @@ -28,7 +28,7 @@ PortWidget::~PortWidget() { // HACK // See ModuleWidget::~ModuleWidget for description if (module) - context()->scene->rackWidget->wireContainer->removeAllWires(this); + app()->scene->rackWidget->wireContainer->removeAllWires(this); } void PortWidget::step() { @@ -48,7 +48,7 @@ void PortWidget::step() { } void PortWidget::draw(NVGcontext *vg) { - WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire; + WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; if (activeWire) { // Dim the PortWidget if the active wire cannot plug into this PortWidget if (type == INPUT ? activeWire->inputPort : activeWire->outputPort) @@ -58,7 +58,7 @@ void PortWidget::draw(NVGcontext *vg) { void PortWidget::onButton(const event::Button &e) { if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { - context()->scene->rackWidget->wireContainer->removeTopWire(this); + app()->scene->rackWidget->wireContainer->removeTopWire(this); // HACK // Update hovered*PortWidget of active wire if applicable @@ -71,8 +71,8 @@ void PortWidget::onButton(const event::Button &e) { void PortWidget::onDragStart(const event::DragStart &e) { // Try to grab wire on top of stack WireWidget *wire = NULL; - if (type == INPUT || !context()->window->isModPressed()) { - wire = context()->scene->rackWidget->wireContainer->getTopWire(this); + if (type == INPUT || !app()->window->isModPressed()) { + wire = app()->scene->rackWidget->wireContainer->getTopWire(this); } if (wire) { @@ -85,13 +85,13 @@ void PortWidget::onDragStart(const event::DragStart &e) { wire = new WireWidget; (type == INPUT ? wire->inputPort : wire->outputPort) = this; } - context()->scene->rackWidget->wireContainer->setActiveWire(wire); + app()->scene->rackWidget->wireContainer->setActiveWire(wire); } void PortWidget::onDragEnd(const event::DragEnd &e) { // FIXME // If the source PortWidget is deleted, this will be called, removing the cable - context()->scene->rackWidget->wireContainer->commitActiveWire(); + app()->scene->rackWidget->wireContainer->commitActiveWire(); } void PortWidget::onDragDrop(const event::DragDrop &e) { @@ -112,12 +112,12 @@ void PortWidget::onDragEnter(const event::DragEnter &e) { // Reject ports if this is an input port and something is already plugged into it if (type == INPUT) { - WireWidget *topWire = context()->scene->rackWidget->wireContainer->getTopWire(this); + WireWidget *topWire = app()->scene->rackWidget->wireContainer->getTopWire(this); if (topWire) return; } - WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire; + WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; if (activeWire) { (type == INPUT ? activeWire->hoveredInputPort : activeWire->hoveredOutputPort) = this; } @@ -128,7 +128,7 @@ void PortWidget::onDragLeave(const event::DragLeave &e) { if (!originPort) return; - WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire; + WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; if (activeWire) { (type == INPUT ? activeWire->hoveredInputPort : activeWire->hoveredOutputPort) = NULL; } diff --git a/src/app/RackScrollWidget.cpp b/src/app/RackScrollWidget.cpp index edf6e75d..55d8f95f 100644 --- a/src/app/RackScrollWidget.cpp +++ b/src/app/RackScrollWidget.cpp @@ -1,17 +1,17 @@ #include "app/RackScrollWidget.hpp" #include "app/Scene.hpp" #include "window.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { void RackScrollWidget::step() { - math::Vec pos = context()->window->mousePos; + math::Vec pos = app()->window->mousePos; math::Rect viewport = getViewport(box.zeroPos()); // Scroll rack if dragging cable near the edge of the screen - if (context()->scene->rackWidget->wireContainer->activeWire) { + if (app()->scene->rackWidget->wireContainer->activeWire) { float margin = 20.0; float speed = 15.0; if (pos.x <= viewport.pos.x + margin) diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index e234e37f..1ee915a2 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -9,7 +9,7 @@ #include "asset.hpp" #include "system.hpp" #include "plugin.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -60,7 +60,7 @@ void RackWidget::clear() { wireContainer->clearChildren(); moduleContainer->clearChildren(); - context()->scene->scrollWidget->offset = math::Vec(0, 0); + app()->scene->scrollWidget->offset = math::Vec(0, 0); } void RackWidget::reset() { @@ -432,7 +432,7 @@ ModuleWidget *RackWidget::moduleFromJson(json_t *moduleJ) { } void RackWidget::pastePresetClipboard() { - const char *moduleJson = glfwGetClipboardString(context()->window->win); + const char *moduleJson = glfwGetClipboardString(app()->window->win); if (!moduleJson) { WARN("Could not get text from clipboard."); return; @@ -539,7 +539,7 @@ void RackWidget::step() { } // Autosave every 15 seconds - int frame = context()->window->frame; + int frame = app()->window->frame; if (frame > 0 && frame % (60 * 15) == 0) { save(asset::user("autosave.vcv")); settings::save(asset::user("settings.json")); @@ -566,7 +566,7 @@ void RackWidget::onButton(const event::Button &e) { OpaqueWidget::onButton(e); if (e.getConsumed() == this) { if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { - context()->scene->moduleBrowser->visible = true; + app()->scene->moduleBrowser->visible = true; } } } diff --git a/src/app/Scene.cpp b/src/app/Scene.cpp index 72674478..fe34bf7c 100644 --- a/src/app/Scene.cpp +++ b/src/app/Scene.cpp @@ -4,7 +4,8 @@ #include "app/Scene.hpp" #include "app/ModuleBrowser.hpp" #include "app/RackScrollWidget.hpp" -#include "context.hpp" +#include "app.hpp" +#include "history.hpp" #include @@ -64,7 +65,7 @@ void Scene::step() { if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, versionMessage.c_str())) { std::thread t(system::openBrowser, "https://vcvrack.com/"); t.detach(); - context()->window->close(); + app()->window->close(); } latestVersion = ""; } @@ -78,50 +79,60 @@ void Scene::onHoverKey(const event::HoverKey &e) { if (e.action == GLFW_PRESS) { switch (e.key) { case GLFW_KEY_N: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { rackWidget->reset(); e.consume(this); } } break; case GLFW_KEY_Q: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { - context()->window->close(); + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { + app()->window->close(); e.consume(this); } } break; case GLFW_KEY_O: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { rackWidget->loadDialog(); e.consume(this); } - if (context()->window->isModPressed() && context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { rackWidget->revert(); e.consume(this); } } break; case GLFW_KEY_S: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { rackWidget->saveDialog(); e.consume(this); } - if (context()->window->isModPressed() && context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { rackWidget->saveAsDialog(); e.consume(this); } } break; case GLFW_KEY_V: { - if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { rackWidget->pastePresetClipboard(); e.consume(this); } } break; + case GLFW_KEY_Z: { + if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) { + app()->history->undo(); + e.consume(this); + } + if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) { + app()->history->redo(); + e.consume(this); + } + } break; case GLFW_KEY_ENTER: case GLFW_KEY_KP_ENTER: { moduleBrowser->visible = true; e.consume(this); } break; case GLFW_KEY_F11: { - context()->window->setFullScreen(!context()->window->isFullScreen()); + app()->window->setFullScreen(!app()->window->isFullScreen()); e.consume(this); } } diff --git a/src/app/Toolbar.cpp b/src/app/Toolbar.cpp index 3cb937bd..86114c0e 100644 --- a/src/app/Toolbar.cpp +++ b/src/app/Toolbar.cpp @@ -10,7 +10,7 @@ #include "ui/PasswordField.hpp" #include "ui/ProgressBar.hpp" #include "app/Scene.hpp" -#include "context.hpp" +#include "app.hpp" #include "settings.hpp" #include "helpers.hpp" #include "system.hpp" @@ -23,7 +23,7 @@ namespace rack { struct MenuButton : Button { void step() override { - box.size.x = bndLabelWidth(context()->window->vg, -1, text.c_str()); + box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()); Widget::step(); } void draw(NVGcontext *vg) override { @@ -38,7 +38,7 @@ struct NewItem : MenuItem { rightText = "(" WINDOW_MOD_KEY_NAME "+N)"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->reset(); + app()->scene->rackWidget->reset(); } }; @@ -49,7 +49,7 @@ struct OpenItem : MenuItem { rightText = "(" WINDOW_MOD_KEY_NAME "+O)"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->loadDialog(); + app()->scene->rackWidget->loadDialog(); } }; @@ -60,7 +60,7 @@ struct SaveItem : MenuItem { rightText = "(" WINDOW_MOD_KEY_NAME "+S)"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->saveDialog(); + app()->scene->rackWidget->saveDialog(); } }; @@ -71,7 +71,7 @@ struct SaveAsItem : MenuItem { rightText = "(" WINDOW_MOD_KEY_NAME "+Shift+S)"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->saveAsDialog(); + app()->scene->rackWidget->saveAsDialog(); } }; @@ -81,7 +81,7 @@ struct SaveTemplateItem : MenuItem { text = "Save template"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->saveTemplate(); + app()->scene->rackWidget->saveTemplate(); } }; @@ -91,7 +91,7 @@ struct RevertItem : MenuItem { text = "Revert"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->revert(); + app()->scene->rackWidget->revert(); } }; @@ -101,7 +101,7 @@ struct DisconnectCablesItem : MenuItem { text = "Disconnect cables"; } void onAction(const event::Action &e) override { - context()->scene->rackWidget->disconnect(); + app()->scene->rackWidget->disconnect(); } }; @@ -112,7 +112,7 @@ struct QuitItem : MenuItem { rightText = "(" WINDOW_MOD_KEY_NAME "+Q)"; } void onAction(const event::Action &e) override { - context()->window->close(); + app()->window->close(); } }; @@ -222,10 +222,10 @@ struct LockModulesItem : MenuItem { struct EnginePauseItem : MenuItem { EnginePauseItem() { text = "Pause engine"; - rightText = CHECKMARK(context()->engine->paused); + rightText = CHECKMARK(app()->engine->paused); } void onAction(const event::Action &e) override { - context()->engine->paused ^= true; + app()->engine->paused ^= true; } }; @@ -235,11 +235,11 @@ struct SampleRateValueItem : MenuItem { SampleRateValueItem(float sampleRate) { this->sampleRate = sampleRate; text = string::f("%.0f Hz", sampleRate); - rightText = CHECKMARK(context()->engine->getSampleRate() == sampleRate); + rightText = CHECKMARK(app()->engine->getSampleRate() == sampleRate); } void onAction(const event::Action &e) override { - context()->engine->setSampleRate(sampleRate); - context()->engine->paused = false; + app()->engine->setSampleRate(sampleRate); + app()->engine->paused = false; } }; @@ -314,7 +314,7 @@ struct AccountEmailField : TextField { } void onSelectKey(const event::SelectKey &e) override { if (e.action == GLFW_PRESS && e.key == GLFW_KEY_TAB) { - context()->event->selectedWidget = passwordField; + app()->event->selectedWidget = passwordField; e.consume(this); return; } @@ -399,7 +399,7 @@ struct SyncItem : MenuItem { // // Display message if we've completed updates // if (completed) { // if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been updated. Close Rack and re-launch it to load new updates.")) { -// context()->window->close(); +// app()->window->close(); // } // completed = false; // } diff --git a/src/app/WireWidget.cpp b/src/app/WireWidget.cpp index 8c6014fd..93b8c1b7 100644 --- a/src/app/WireWidget.cpp +++ b/src/app/WireWidget.cpp @@ -4,7 +4,7 @@ #include "componentlibrary.hpp" #include "window.hpp" #include "event.hpp" -#include "context.hpp" +#include "app.hpp" #include "settings.hpp" @@ -111,12 +111,12 @@ void WireWidget::updateWire() { wire->outputId = outputPort->portId; wire->inputModule = inputPort->module; wire->inputId = inputPort->portId; - context()->engine->addWire(wire); + app()->engine->addWire(wire); } } else { if (wire) { - context()->engine->removeWire(wire); + app()->engine->removeWire(wire); delete wire; wire = NULL; } @@ -125,25 +125,25 @@ void WireWidget::updateWire() { math::Vec WireWidget::getOutputPos() { if (outputPort) { - return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), context()->scene->rackWidget); + return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); } else if (hoveredOutputPort) { - return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), context()->scene->rackWidget); + return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); } else { - return context()->scene->rackWidget->lastMousePos; + return app()->scene->rackWidget->lastMousePos; } } math::Vec WireWidget::getInputPos() { if (inputPort) { - return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), context()->scene->rackWidget); + return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); } else if (hoveredInputPort) { - return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), context()->scene->rackWidget); + return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), app()->scene->rackWidget); } else { - return context()->scene->rackWidget->lastMousePos; + return app()->scene->rackWidget->lastMousePos; } } @@ -167,14 +167,14 @@ void WireWidget::draw(NVGcontext *vg) { float opacity = settings::wireOpacity; float tension = settings::wireTension; - WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire; + WireWidget *activeWire = app()->scene->rackWidget->wireContainer->activeWire; if (activeWire) { // Draw as opaque if the wire is active if (activeWire == this) opacity = 1.0; } else { - PortWidget *hoveredPort = dynamic_cast(context()->event->hoveredWidget); + PortWidget *hoveredPort = dynamic_cast(app()->event->hoveredWidget); if (hoveredPort && (hoveredPort == outputPort || hoveredPort == inputPort)) opacity = 1.0; } diff --git a/src/context.cpp b/src/context.cpp deleted file mode 100644 index 1e26619a..00000000 --- a/src/context.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "context.hpp" - - -namespace rack { - - -static Context c; - - -Context *context() { - return &c; -} - - -} // namespace rack diff --git a/src/engine/Light.cpp b/src/engine/Light.cpp index 93d1cebc..d7ff1ee3 100644 --- a/src/engine/Light.cpp +++ b/src/engine/Light.cpp @@ -1,6 +1,6 @@ #include "engine/Light.hpp" #include "engine/Engine.hpp" -#include "context.hpp" +#include "app.hpp" namespace rack { @@ -16,7 +16,7 @@ void Light::setBrightnessSmooth(float brightness, float frames) { float v = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; if (v < value) { // Fade out light with lambda = framerate - value += (v - value) * context()->engine->getSampleTime() * frames * 60.f; + value += (v - value) * app()->engine->getSampleTime() * frames * 60.f; } else { // Immediately illuminate light diff --git a/src/history.cpp b/src/history.cpp new file mode 100644 index 00000000..590fe08d --- /dev/null +++ b/src/history.cpp @@ -0,0 +1,22 @@ +#include "history.hpp" + + +namespace rack { +namespace history { + + +void State::push(Action *action) { + +} + +void State::undo() { + DEBUG("undo"); +} + +void State::redo() { + DEBUG("redo"); +} + + +} // namespace history +} // namespace rack diff --git a/src/main.cpp b/src/main.cpp index c76307fa..ef42b6e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ #include "engine/Engine.hpp" #include "app/Scene.hpp" #include "plugin.hpp" -#include "context.hpp" +#include "app.hpp" #include "ui.hpp" #include @@ -79,12 +79,8 @@ int main(int argc, char *argv[]) { plugin::init(devMode); // Initialize app - context()->event = new event::State; - context()->window = new Window; - context()->engine = new Engine; - context()->scene = new Scene; - context()->scene->devMode = devMode; - context()->event->rootWidget = context()->scene; + appInit(); + app()->scene->devMode = devMode; settings::load(asset::user("settings.json")); if (patchFile.empty()) { @@ -94,36 +90,29 @@ int main(int argc, char *argv[]) { settings::save(asset::user("settings.json")); settings::skipLoadOnLaunch = false; if (oldSkipLoadOnLaunch && osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, "Rack has recovered from a crash, possibly caused by a faulty module in your patch. Clear your patch and start over?")) { - context()->scene->rackWidget->lastPath = ""; + app()->scene->rackWidget->lastPath = ""; } else { // Load autosave - std::string oldLastPath = context()->scene->rackWidget->lastPath; - context()->scene->rackWidget->load(asset::user("autosave.vcv")); - context()->scene->rackWidget->lastPath = oldLastPath; + std::string oldLastPath = app()->scene->rackWidget->lastPath; + app()->scene->rackWidget->load(asset::user("autosave.vcv")); + app()->scene->rackWidget->lastPath = oldLastPath; } } else { // Load patch - context()->scene->rackWidget->load(patchFile); - context()->scene->rackWidget->lastPath = patchFile; + app()->scene->rackWidget->load(patchFile); + app()->scene->rackWidget->lastPath = patchFile; } - context()->engine->start(); - context()->window->run(); - context()->engine->stop(); + app()->engine->start(); + app()->window->run(); + app()->engine->stop(); // Destroy app - context()->scene->rackWidget->save(asset::user("autosave.vcv")); + app()->scene->rackWidget->save(asset::user("autosave.vcv")); settings::save(asset::user("settings.json")); - delete context()->scene; - context()->scene = NULL; - delete context()->event; - context()->event = NULL; - delete context()->engine; - context()->engine = NULL; - delete context()->window; - context()->window = NULL; + appDestroy(); // Destroy environment plugin::destroy(); diff --git a/src/plugin.cpp b/src/plugin.cpp index 5a779632..0ee3d1d0 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -3,7 +3,7 @@ #include "network.hpp" #include "asset.hpp" #include "string.hpp" -#include "context.hpp" +#include "app.hpp" #include "app/common.hpp" #include "plugin/callbacks.hpp" diff --git a/src/settings.cpp b/src/settings.cpp index 9e23f871..6241afa6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -4,7 +4,7 @@ #include "app/Scene.hpp" #include "app/ModuleBrowser.hpp" #include "engine/Engine.hpp" -#include "context.hpp" +#include "app.hpp" #include @@ -20,14 +20,14 @@ static json_t *settingsToJson() { json_t *tokenJ = json_string(plugin::token.c_str()); json_object_set_new(rootJ, "token", tokenJ); - if (!context()->window->isMaximized()) { + if (!app()->window->isMaximized()) { // windowSize - math::Vec windowSize = context()->window->getWindowSize(); + math::Vec windowSize = app()->window->getWindowSize(); json_t *windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y); json_object_set_new(rootJ, "windowSize", windowSizeJ); // windowPos - math::Vec windowPos = context()->window->getWindowPos(); + math::Vec windowPos = app()->window->getWindowPos(); json_t *windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y); json_object_set_new(rootJ, "windowPos", windowPosJ); } @@ -45,15 +45,15 @@ static json_t *settingsToJson() { json_object_set_new(rootJ, "zoom", zoomJ); // allowCursorLock - json_t *allowCursorLockJ = json_boolean(context()->window->allowCursorLock); + json_t *allowCursorLockJ = json_boolean(app()->window->allowCursorLock); json_object_set_new(rootJ, "allowCursorLock", allowCursorLockJ); // sampleRate - json_t *sampleRateJ = json_real(context()->engine->getSampleRate()); + json_t *sampleRateJ = json_real(app()->engine->getSampleRate()); json_object_set_new(rootJ, "sampleRate", sampleRateJ); // lastPath - json_t *lastPathJ = json_string(context()->scene->rackWidget->lastPath.c_str()); + json_t *lastPathJ = json_string(app()->scene->rackWidget->lastPath.c_str()); json_object_set_new(rootJ, "lastPath", lastPathJ); // skipLoadOnLaunch @@ -87,7 +87,7 @@ static void settingsFromJson(json_t *rootJ) { if (windowSizeJ) { double width, height; json_unpack(windowSizeJ, "[F, F]", &width, &height); - context()->window->setWindowSize(math::Vec(width, height)); + app()->window->setWindowSize(math::Vec(width, height)); } // windowPos @@ -95,7 +95,7 @@ static void settingsFromJson(json_t *rootJ) { if (windowPosJ) { double x, y; json_unpack(windowPosJ, "[F, F]", &x, &y); - context()->window->setWindowPos(math::Vec(x, y)); + app()->window->setWindowPos(math::Vec(x, y)); } // wireOpacity @@ -116,19 +116,19 @@ static void settingsFromJson(json_t *rootJ) { // allowCursorLock json_t *allowCursorLockJ = json_object_get(rootJ, "allowCursorLock"); if (allowCursorLockJ) - context()->window->allowCursorLock = json_is_true(allowCursorLockJ); + app()->window->allowCursorLock = json_is_true(allowCursorLockJ); // sampleRate json_t *sampleRateJ = json_object_get(rootJ, "sampleRate"); if (sampleRateJ) { float sampleRate = json_number_value(sampleRateJ); - context()->engine->setSampleRate(sampleRate); + app()->engine->setSampleRate(sampleRate); } // lastPath json_t *lastPathJ = json_object_get(rootJ, "lastPath"); if (lastPathJ) - context()->scene->rackWidget->lastPath = json_string_value(lastPathJ); + app()->scene->rackWidget->lastPath = json_string_value(lastPathJ); // skipLoadOnLaunch json_t *skipLoadOnLaunchJ = json_object_get(rootJ, "skipLoadOnLaunch"); diff --git a/src/ui/MenuItem.cpp b/src/ui/MenuItem.cpp index 03a5849a..06181278 100644 --- a/src/ui/MenuItem.cpp +++ b/src/ui/MenuItem.cpp @@ -7,7 +7,7 @@ namespace rack { void MenuItem::draw(NVGcontext *vg) { BNDwidgetState state = BND_DEFAULT; - if (context()->event->hoveredWidget == this) + if (app()->event->hoveredWidget == this) state = BND_HOVER; // Set active state if this MenuItem @@ -30,9 +30,9 @@ void MenuItem::draw(NVGcontext *vg) { void MenuItem::step() { // Add 10 more pixels because measurements on high-DPI screens are sometimes too small for some reason const float rightPadding = 10.0; - // HACK use context()->window->vg from the window. - // All this does is inspect the font, so it shouldn't modify context()->window->vg and should work when called from a FramebufferWidget for example. - box.size.x = bndLabelWidth(context()->window->vg, -1, text.c_str()) + bndLabelWidth(context()->window->vg, -1, rightText.c_str()) + rightPadding; + // HACK use app()->window->vg from the window. + // All this does is inspect the font, so it shouldn't modify app()->window->vg and should work when called from a FramebufferWidget for example. + box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()) + bndLabelWidth(app()->window->vg, -1, rightText.c_str()) + rightPadding; Widget::step(); } diff --git a/src/ui/ScrollBar.cpp b/src/ui/ScrollBar.cpp index 138eb668..99525933 100644 --- a/src/ui/ScrollBar.cpp +++ b/src/ui/ScrollBar.cpp @@ -1,6 +1,6 @@ #include "ui/ScrollBar.hpp" #include "ui/ScrollWidget.hpp" -#include "context.hpp" +#include "app.hpp" #include "window.hpp" @@ -20,7 +20,7 @@ void ScrollBar::draw(NVGcontext *vg) { void ScrollBar::onDragStart(const event::DragStart &e) { state = BND_ACTIVE; - context()->window->cursorLock(); + app()->window->cursorLock(); } void ScrollBar::onDragMove(const event::DragMove &e) { @@ -34,7 +34,7 @@ void ScrollBar::onDragMove(const event::DragMove &e) { void ScrollBar::onDragEnd(const event::DragEnd &e) { state = BND_DEFAULT; - context()->window->cursorUnlock(); + app()->window->cursorUnlock(); } diff --git a/src/ui/ScrollWidget.cpp b/src/ui/ScrollWidget.cpp index d0598b0e..070fbf61 100644 --- a/src/ui/ScrollWidget.cpp +++ b/src/ui/ScrollWidget.cpp @@ -1,5 +1,5 @@ #include "ui/ScrollWidget.hpp" -#include "context.hpp" +#include "app.hpp" #include "event.hpp" @@ -70,25 +70,25 @@ void ScrollWidget::step() { void ScrollWidget::onHover(const event::Hover &e) { // Scroll with arrow keys - if (!context()->event->selectedWidget) { + if (!app()->event->selectedWidget) { float arrowSpeed = 30.0; - if (context()->window->isShiftPressed() && context()->window->isModPressed()) + if (app()->window->isShiftPressed() && app()->window->isModPressed()) arrowSpeed /= 16.0; - else if (context()->window->isShiftPressed()) + else if (app()->window->isShiftPressed()) arrowSpeed *= 4.0; - else if (context()->window->isModPressed()) + else if (app()->window->isModPressed()) arrowSpeed /= 4.0; - if (glfwGetKey(context()->window->win, GLFW_KEY_LEFT) == GLFW_PRESS) { + if (glfwGetKey(app()->window->win, GLFW_KEY_LEFT) == GLFW_PRESS) { offset.x -= arrowSpeed; } - if (glfwGetKey(context()->window->win, GLFW_KEY_RIGHT) == GLFW_PRESS) { + if (glfwGetKey(app()->window->win, GLFW_KEY_RIGHT) == GLFW_PRESS) { offset.x += arrowSpeed; } - if (glfwGetKey(context()->window->win, GLFW_KEY_UP) == GLFW_PRESS) { + if (glfwGetKey(app()->window->win, GLFW_KEY_UP) == GLFW_PRESS) { offset.y -= arrowSpeed; } - if (glfwGetKey(context()->window->win, GLFW_KEY_DOWN) == GLFW_PRESS) { + if (glfwGetKey(app()->window->win, GLFW_KEY_DOWN) == GLFW_PRESS) { offset.y += arrowSpeed; } } diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index 4c554584..38c419b6 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -11,9 +11,9 @@ void TextField::draw(NVGcontext *vg) { nvgScissor(vg, 0, 0, box.size.x, box.size.y); BNDwidgetState state; - if (this == context()->event->selectedWidget) + if (this == app()->event->selectedWidget) state = BND_ACTIVE; - else if (this == context()->event->hoveredWidget) + else if (this == app()->event->hoveredWidget) state = BND_HOVER; else state = BND_DEFAULT; @@ -37,7 +37,7 @@ void TextField::onButton(const event::Button &e) { } void TextField::onHover(const event::Hover &e) { - if (this == context()->event->draggedWidget) { + if (this == app()->event->draggedWidget) { int pos = getTextPosition(e.pos); if (pos != selection) { cursor = pos; @@ -94,7 +94,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { } } break; case GLFW_KEY_LEFT: { - if (context()->window->isModPressed()) { + if (app()->window->isModPressed()) { while (--cursor > 0) { if (text[cursor] == ' ') break; @@ -103,12 +103,12 @@ void TextField::onSelectKey(const event::SelectKey &e) { else { cursor--; } - if (!context()->window->isShiftPressed()) { + if (!app()->window->isShiftPressed()) { selection = cursor; } } break; case GLFW_KEY_RIGHT: { - if (context()->window->isModPressed()) { + if (app()->window->isModPressed()) { while (++cursor < (int) text.size()) { if (text[cursor] == ' ') break; @@ -117,7 +117,7 @@ void TextField::onSelectKey(const event::SelectKey &e) { else { cursor++; } - if (!context()->window->isShiftPressed()) { + if (!app()->window->isShiftPressed()) { selection = cursor; } } break; @@ -128,33 +128,33 @@ void TextField::onSelectKey(const event::SelectKey &e) { selection = cursor = text.size(); } break; case GLFW_KEY_V: { - if (context()->window->isModPressed()) { - const char *newText = glfwGetClipboardString(context()->window->win); + if (app()->window->isModPressed()) { + const char *newText = glfwGetClipboardString(app()->window->win); if (newText) insertText(newText); } } break; case GLFW_KEY_X: { - if (context()->window->isModPressed()) { + if (app()->window->isModPressed()) { if (cursor != selection) { int begin = std::min(cursor, selection); std::string selectedText = text.substr(begin, std::abs(selection - cursor)); - glfwSetClipboardString(context()->window->win, selectedText.c_str()); + glfwSetClipboardString(app()->window->win, selectedText.c_str()); insertText(""); } } } break; case GLFW_KEY_C: { - if (context()->window->isModPressed()) { + if (app()->window->isModPressed()) { if (cursor != selection) { int begin = std::min(cursor, selection); std::string selectedText = text.substr(begin, std::abs(selection - cursor)); - glfwSetClipboardString(context()->window->win, selectedText.c_str()); + glfwSetClipboardString(app()->window->win, selectedText.c_str()); } } } break; case GLFW_KEY_A: { - if (context()->window->isModPressed()) { + if (app()->window->isModPressed()) { selectAll(); } } break; @@ -203,7 +203,7 @@ void TextField::selectAll() { } int TextField::getTextPosition(math::Vec mousePos) { - return bndTextFieldTextPosition(context()->window->vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); + return bndTextFieldTextPosition(app()->window->vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str(), mousePos.x, mousePos.y); } diff --git a/src/ui/Tooltip.cpp b/src/ui/Tooltip.cpp index 4972a25b..0938c675 100644 --- a/src/ui/Tooltip.cpp +++ b/src/ui/Tooltip.cpp @@ -1,5 +1,5 @@ #include "ui/Tooltip.hpp" -#include "context.hpp" +#include "app.hpp" #include "window.hpp" @@ -8,8 +8,8 @@ namespace rack { void Tooltip::step() { // Wrap size to contents - box.size.x = bndLabelWidth(context()->window->vg, -1, text.c_str()) + 10.0; - box.size.y = bndLabelHeight(context()->window->vg, -1, text.c_str(), INFINITY); + box.size.x = bndLabelWidth(app()->window->vg, -1, text.c_str()) + 10.0; + box.size.y = bndLabelHeight(app()->window->vg, -1, text.c_str(), INFINITY); Widget::step(); } diff --git a/src/widgets/FramebufferWidget.cpp b/src/widgets/FramebufferWidget.cpp index f0bd0b9a..f324c01a 100644 --- a/src/widgets/FramebufferWidget.cpp +++ b/src/widgets/FramebufferWidget.cpp @@ -1,5 +1,5 @@ #include "widgets/FramebufferWidget.hpp" -#include "context.hpp" +#include "app.hpp" #include #include @@ -55,7 +55,7 @@ void FramebufferWidget::draw(NVGcontext *vg) { internal->box.pos = internal->box.pos.mult(s).floor(); internal->box.size = internal->box.size.mult(s).ceil().plus(math::Vec(1, 1)); - math::Vec fbSize = internal->box.size.mult(context()->window->pixelRatio * oversample); + math::Vec fbSize = internal->box.size.mult(app()->window->pixelRatio * oversample); if (!fbSize.isFinite()) return; @@ -66,7 +66,7 @@ void FramebufferWidget::draw(NVGcontext *vg) { // Delete old one first to free up GPU memory internal->setFramebuffer(NULL); // Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context. - NVGLUframebuffer *fb = nvgluCreateFramebuffer(context()->window->vg, fbSize.x, fbSize.y, 0); + NVGLUframebuffer *fb = nvgluCreateFramebuffer(app()->window->vg, fbSize.x, fbSize.y, 0); if (!fb) return; internal->setFramebuffer(fb); @@ -76,10 +76,10 @@ void FramebufferWidget::draw(NVGcontext *vg) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - NVGcontext *framebufferVg = context()->window->framebufferVg; - nvgBeginFrame(framebufferVg, fbSize.x, fbSize.y, context()->window->pixelRatio * oversample); + NVGcontext *framebufferVg = app()->window->framebufferVg; + nvgBeginFrame(framebufferVg, fbSize.x, fbSize.y, app()->window->pixelRatio * oversample); - nvgScale(framebufferVg, context()->window->pixelRatio * oversample, context()->window->pixelRatio * oversample); + nvgScale(framebufferVg, app()->window->pixelRatio * oversample, app()->window->pixelRatio * oversample); // Use local scaling nvgTranslate(framebufferVg, bf.x, bf.y); nvgTranslate(framebufferVg, -internal->box.pos.x, -internal->box.pos.y); diff --git a/src/widgets/Widget.cpp b/src/widgets/Widget.cpp index bd61dd13..754e1cbe 100644 --- a/src/widgets/Widget.cpp +++ b/src/widgets/Widget.cpp @@ -1,6 +1,6 @@ #include "widgets/Widget.hpp" #include "event.hpp" -#include "context.hpp" +#include "app.hpp" #include @@ -58,7 +58,7 @@ void Widget::removeChild(Widget *child) { // Make sure `this` is the child's parent assert(child->parent == this); // Prepare to remove widget from the event state - context()->event->finalizeWidget(child); + app()->event->finalizeWidget(child); // Delete child from children list auto it = std::find(children.begin(), children.end(), child); assert(it != children.end()); @@ -69,7 +69,7 @@ void Widget::removeChild(Widget *child) { void Widget::clearChildren() { for (Widget *child : children) { - context()->event->finalizeWidget(child); + app()->event->finalizeWidget(child); child->parent = NULL; delete child; } @@ -81,7 +81,7 @@ void Widget::step() { Widget *child = *it; // Delete children if a delete is requested if (child->requestedDelete) { - context()->event->finalizeWidget(child); + app()->event->finalizeWidget(child); it = children.erase(it); child->parent = NULL; delete child; @@ -107,7 +107,7 @@ void Widget::draw(NVGcontext *vg) { child->draw(vg); // Draw red hitboxes - // if (context()->event->hoveredWidget == child) { + // if (app()->event->hoveredWidget == child) { // nvgBeginPath(vg); // nvgRect(vg, 0, 0, child->box.size.x, child->box.size.y); // nvgFillColor(vg, nvgRGBAf(1, 0, 0, 0.5)); diff --git a/src/window.cpp b/src/window.cpp index b1494cef..ee9461ce 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -4,7 +4,7 @@ #include "keyboard.hpp" #include "gamepad.hpp" #include "event.hpp" -#include "context.hpp" +#include "app.hpp" #include #include @@ -70,7 +70,7 @@ static void mouseButtonCallback(GLFWwindow *win, int button, int action, int mod } #endif - context()->event->handleButton(window->mousePos, button, action, mods); + app()->event->handleButton(window->mousePos, button, action, mods); } static void Window_mouseButtonStickyPop(Window *window) { @@ -111,12 +111,12 @@ static void cursorPosCallback(GLFWwindow *win, double xpos, double ypos) { window->mousePos = mousePos; - context()->event->handleHover(mousePos, mouseDelta); + app()->event->handleHover(mousePos, mouseDelta); } static void cursorEnterCallback(GLFWwindow *win, int entered) { if (!entered) { - context()->event->handleLeave(); + app()->event->handleLeave(); } } @@ -129,17 +129,17 @@ static void scrollCallback(GLFWwindow *win, double x, double y) { #endif scrollDelta = scrollDelta.mult(50.0); - context()->event->handleScroll(window->mousePos, scrollDelta); + app()->event->handleScroll(window->mousePos, scrollDelta); } static void charCallback(GLFWwindow *win, unsigned int codepoint) { Window *window = (Window*) glfwGetWindowUserPointer(win); - context()->event->handleText(window->mousePos, codepoint); + app()->event->handleText(window->mousePos, codepoint); } static void keyCallback(GLFWwindow *win, int key, int scancode, int action, int mods) { Window *window = (Window*) glfwGetWindowUserPointer(win); - context()->event->handleKey(window->mousePos, key, scancode, action, mods); + app()->event->handleKey(window->mousePos, key, scancode, action, mods); // Keyboard MIDI driver if (!(mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER))) { @@ -158,7 +158,7 @@ static void dropCallback(GLFWwindow *win, int count, const char **paths) { for (int i = 0; i < count; i++) { pathsVec.push_back(paths[i]); } - context()->event->handleDrop(window->mousePos, pathsVec); + app()->event->handleDrop(window->mousePos, pathsVec); } static void errorCallback(int error, const char *description) { @@ -280,7 +280,7 @@ static void Window_renderGui(Window *window) { nvgReset(window->vg); nvgScale(window->vg, window->pixelRatio, window->pixelRatio); - context()->event->rootWidget->draw(window->vg); + app()->event->rootWidget->draw(window->vg); glViewport(0, 0, width, height); glClearColor(0.0, 0.0, 0.0, 1.0); @@ -312,9 +312,9 @@ void Window::run() { windowTitle = APP_NAME; windowTitle += " "; windowTitle += APP_VERSION; - if (!context()->scene->rackWidget->lastPath.empty()) { + if (!app()->scene->rackWidget->lastPath.empty()) { windowTitle += " - "; - windowTitle += string::filename(context()->scene->rackWidget->lastPath); + windowTitle += string::filename(app()->scene->rackWidget->lastPath); } if (windowTitle != internal->lastWindowTitle) { glfwSetWindowTitle(win, windowTitle.c_str()); @@ -326,7 +326,7 @@ void Window::run() { glfwGetWindowContentScale(win, &newPixelRatio, NULL); newPixelRatio = std::round(newPixelRatio); if (newPixelRatio != pixelRatio) { - context()->event->handleZoom(); + app()->event->handleZoom(); pixelRatio = newPixelRatio; } @@ -337,10 +337,10 @@ void Window::run() { glfwGetWindowSize(win, &windowWidth, &windowHeight); windowRatio = (float)width / windowWidth; - context()->event->rootWidget->box.size = math::Vec(width, height).div(pixelRatio); + app()->event->rootWidget->box.size = math::Vec(width, height).div(pixelRatio); // Step scene - context()->event->rootWidget->step(); + app()->event->rootWidget->step(); // Render bool visible = glfwGetWindowAttrib(win, GLFW_VISIBLE) && !glfwGetWindowAttrib(win, GLFW_ICONIFIED); @@ -444,7 +444,7 @@ bool Window::isFullScreen() { //////////////////// Font::Font(const std::string &filename) { - handle = nvgCreateFont(context()->window->vg, filename.c_str(), filename.c_str()); + handle = nvgCreateFont(app()->window->vg, filename.c_str(), filename.c_str()); if (handle >= 0) { INFO("Loaded font %s", filename.c_str()); } @@ -470,7 +470,7 @@ std::shared_ptr Font::load(const std::string &filename) { //////////////////// Image::Image(const std::string &filename) { - handle = nvgCreateImage(context()->window->vg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); + handle = nvgCreateImage(app()->window->vg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); if (handle > 0) { INFO("Loaded image %s", filename.c_str()); } @@ -481,7 +481,7 @@ Image::Image(const std::string &filename) { Image::~Image() { // TODO What if handle is invalid? - nvgDeleteImage(context()->window->vg, handle); + nvgDeleteImage(app()->window->vg, handle); } std::shared_ptr Image::load(const std::string &filename) {