@@ -355,6 +355,7 @@ extern std::string gApplicationVersion; | |||||
extern std::string gApiHost; | extern std::string gApiHost; | ||||
// Easy access to "singleton" widgets | // Easy access to "singleton" widgets | ||||
extern RackScene *gRackScene; | |||||
extern RackWidget *gRackWidget; | extern RackWidget *gRackWidget; | ||||
extern Toolbar *gToolbar; | extern Toolbar *gToolbar; | ||||
@@ -61,6 +61,10 @@ inline float eucmodf(float a, float base) { | |||||
return mod < 0.0 ? mod + base : mod; | return mod < 0.0 ? mod + base : mod; | ||||
} | } | ||||
inline float nearf(float a, float b, float epsilon = 1e-6) { | |||||
return fabsf(a - b) <= epsilon; | |||||
} | |||||
/** Limits a value between a minimum and maximum | /** Limits a value between a minimum and maximum | ||||
If min > max, the limits are switched | If min > max, the limits are switched | ||||
*/ | */ | ||||
@@ -14,10 +14,12 @@ std::string gApiHost = "http://api.vcvrack.com"; | |||||
RackWidget *gRackWidget = NULL; | RackWidget *gRackWidget = NULL; | ||||
Toolbar *gToolbar = NULL; | Toolbar *gToolbar = NULL; | ||||
RackScene *gRackScene = NULL; | |||||
void sceneInit() { | void sceneInit() { | ||||
gScene = new RackScene(); | |||||
gRackScene = new RackScene(); | |||||
gScene = gRackScene; | |||||
} | } | ||||
void sceneDestroy() { | void sceneDestroy() { | ||||
@@ -62,9 +62,6 @@ void RackScene::step() { | |||||
.plus(Vec(500, 500)) | .plus(Vec(500, 500)) | ||||
.div(zoomWidget->zoom); | .div(zoomWidget->zoom); | ||||
// Set zoom from the toolbar's zoom slider | |||||
zoomWidget->setZoom(gToolbar->zoomSlider->value / 100.0); | |||||
Scene::step(); | Scene::step(); | ||||
zoomWidget->box.size = gRackWidget->box.size.mult(zoomWidget->zoom); | zoomWidget->box.size = gRackWidget->box.size.mult(zoomWidget->zoom); | ||||
@@ -1,4 +1,5 @@ | |||||
#include "app.hpp" | #include "app.hpp" | ||||
#include "gui.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -17,7 +18,8 @@ struct PanelBorder : TransparentWidget { | |||||
SVGPanel::SVGPanel() { | SVGPanel::SVGPanel() { | ||||
oversample = 2.0; | |||||
if (nearf(gPixelRatio, 1.0)) | |||||
oversample = 2.0; | |||||
} | } | ||||
void SVGPanel::setBackground(std::shared_ptr<SVG> svg) { | void SVGPanel::setBackground(std::shared_ptr<SVG> svg) { | ||||
@@ -148,12 +148,18 @@ Toolbar::Toolbar() { | |||||
xPos += margin; | xPos += margin; | ||||
{ | { | ||||
zoomSlider = new Slider(); | |||||
struct ZoomSlider : Slider { | |||||
void onAction() override { | |||||
Slider::onAction(); | |||||
gRackScene->zoomWidget->setZoom(value / 100.0); | |||||
} | |||||
}; | |||||
zoomSlider = new ZoomSlider(); | |||||
zoomSlider->box.pos = Vec(xPos, margin); | zoomSlider->box.pos = Vec(xPos, margin); | ||||
zoomSlider->box.size.x = 150; | zoomSlider->box.size.x = 150; | ||||
zoomSlider->label = "Zoom"; | zoomSlider->label = "Zoom"; | ||||
zoomSlider->unit = "%"; | zoomSlider->unit = "%"; | ||||
zoomSlider->setLimits(50.0, 200.0); | |||||
zoomSlider->setLimits(25.0, 200.0); | |||||
zoomSlider->setDefaultValue(100.0); | zoomSlider->setDefaultValue(100.0); | ||||
addChild(zoomSlider); | addChild(zoomSlider); | ||||
xPos += zoomSlider->box.size.x; | xPos += zoomSlider->box.size.x; | ||||
@@ -28,7 +28,7 @@ static json_t *settingsToJson() { | |||||
json_object_set_new(rootJ, "wireTension", tensionJ); | json_object_set_new(rootJ, "wireTension", tensionJ); | ||||
// zoom | // zoom | ||||
float zoom = gToolbar->zoomSlider->value; | |||||
float zoom = gRackScene->zoomWidget->zoom; | |||||
json_t *zoomJ = json_real(zoom); | json_t *zoomJ = json_real(zoom); | ||||
json_object_set_new(rootJ, "zoom", zoomJ); | json_object_set_new(rootJ, "zoom", zoomJ); | ||||
@@ -69,8 +69,10 @@ static void settingsFromJson(json_t *rootJ) { | |||||
// zoom | // zoom | ||||
json_t *zoomJ = json_object_get(rootJ, "zoom"); | json_t *zoomJ = json_object_get(rootJ, "zoom"); | ||||
if (zoomJ) | |||||
gToolbar->zoomSlider->value = json_number_value(zoomJ); | |||||
if (zoomJ) { | |||||
gRackScene->zoomWidget->setZoom(clampf(json_number_value(zoomJ), 0.25, 4.0)); | |||||
gToolbar->zoomSlider->setValue(json_number_value(zoomJ) * 100.0); | |||||
} | |||||
// allowCursorLock | // allowCursorLock | ||||
json_t *allowCursorLockJ = json_object_get(rootJ, "allowCursorLock"); | json_t *allowCursorLockJ = json_object_get(rootJ, "allowCursorLock"); | ||||
@@ -60,6 +60,7 @@ void FramebufferWidget::draw(NVGcontext *vg) { | |||||
if (fbSize.x <= 0.0 || fbSize.y <= 0.0) | if (fbSize.x <= 0.0 || fbSize.y <= 0.0) | ||||
return; | return; | ||||
// printf("rendering framebuffer %f %f\n", fbSize.x, fbSize.y); | |||||
// Delete old one first to free up GPU memory | // Delete old one first to free up GPU memory | ||||
internal->setFramebuffer(NULL); | internal->setFramebuffer(NULL); | ||||
// Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context. | // Create a framebuffer from the main nanovg context. We will draw to this in the secondary nanovg context. | ||||
@@ -23,11 +23,13 @@ void Slider::onDragMove(Vec mouseRel) { | |||||
void Slider::onDragEnd() { | void Slider::onDragEnd() { | ||||
state = BND_DEFAULT; | state = BND_DEFAULT; | ||||
guiCursorUnlock(); | guiCursorUnlock(); | ||||
onAction(); | |||||
} | } | ||||
void Slider::onMouseDownOpaque(int button) { | void Slider::onMouseDownOpaque(int button) { | ||||
if (button == 1) { | if (button == 1) { | ||||
setValue(defaultValue); | setValue(defaultValue); | ||||
onAction(); | |||||
} | } | ||||
} | } | ||||