Browse Source

Merge branch 'master' of https://github.com/VCVRack/Rack into 2017-10-bontric-midiCC-fix

tags/v0.5.0
ben 7 years ago
parent
commit
786ee4cdc0
25 changed files with 115 additions and 62 deletions
  1. +1
    -0
      .gitignore
  2. +2
    -0
      include/app.hpp
  3. +2
    -1
      include/engine.hpp
  4. +21
    -2
      include/math.hpp
  5. +11
    -1
      include/widgets.hpp
  6. +3
    -1
      src/app.cpp
  7. +0
    -3
      src/app/RackScene.cpp
  8. +1
    -1
      src/app/RackScrollWidget.cpp
  9. +1
    -0
      src/app/RackWidget.cpp
  10. +8
    -0
      src/app/SVGPanel.cpp
  11. +10
    -4
      src/app/Toolbar.cpp
  12. +4
    -8
      src/app/WireWidget.cpp
  13. +3
    -3
      src/core/AudioInterface.cpp
  14. +1
    -1
      src/core/MidiClockToCV.cpp
  15. +2
    -2
      src/core/MidiIO.cpp
  16. +1
    -1
      src/core/QuadMidiToCV.cpp
  17. +2
    -2
      src/engine.cpp
  18. +9
    -5
      src/gui.cpp
  19. +5
    -3
      src/settings.cpp
  20. +2
    -6
      src/widgets/FramebufferWidget.cpp
  21. +1
    -0
      src/widgets/SVGWidget.cpp
  22. +2
    -0
      src/widgets/Slider.cpp
  23. +1
    -1
      src/widgets/Tooltip.cpp
  24. +17
    -17
      src/widgets/Widget.cpp
  25. +5
    -0
      src/widgets/ZoomWidget.cpp

+ 1
- 0
.gitignore View File

@@ -8,3 +8,4 @@
*.vcv
/patches
/design
.DS_Store

+ 2
- 0
include/app.hpp View File

@@ -155,6 +155,7 @@ struct Panel : TransparentWidget {
};

struct SVGPanel : FramebufferWidget {
void step() override;
void setBackground(std::shared_ptr<SVG> svg);
};

@@ -354,6 +355,7 @@ extern std::string gApplicationVersion;
extern std::string gApiHost;

// Easy access to "singleton" widgets
extern RackScene *gRackScene;
extern RackWidget *gRackWidget;
extern Toolbar *gToolbar;



+ 2
- 1
include/engine.hpp View File

@@ -30,8 +30,9 @@ struct Output {
};

struct Light {
/** The square of the brightness value */
float value = 0.0;
void setSmooth(float v);
void setBrightnessSmooth(float brightness);
};




+ 21
- 2
include/math.hpp View File

@@ -2,7 +2,7 @@

#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <cmath>


namespace rack {
@@ -61,6 +61,10 @@ inline float eucmodf(float a, float base) {
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
If min > max, the limits are switched
*/
@@ -204,7 +208,7 @@ struct Vec {
return x == 0.0 && y == 0.0;
}
bool isFinite() {
return isfinite(x) && isfinite(y);
return std::isfinite(x) && std::isfinite(y);
}
Vec clamp(Rect bound);
};
@@ -267,6 +271,21 @@ struct Rect {
r.pos.y = clampf(pos.y, bound.pos.y, bound.pos.y + bound.size.y - size.y);
return r;
}
/** Expands this Rect to contain `other` */
Rect expand(Rect other) {
Rect r;
r.pos.x = fminf(pos.x, other.pos.x);
r.pos.y = fminf(pos.y, other.pos.y);
r.size.x = fmaxf(pos.x + size.x, other.pos.x + other.size.x) - r.pos.x;
r.size.y = fmaxf(pos.y + size.y, other.pos.y + other.size.y) - r.pos.y;
return r;
}
/** Returns a Rect with its position set to zero */
Rect zeroPos() {
Rect r;
r.size = size;
return r;
}
};




+ 11
- 1
include/widgets.hpp View File

@@ -56,8 +56,13 @@ struct Widget {

virtual ~Widget();

Vec getAbsolutePos();
Rect getChildrenBoundingBox();
/** Returns `v` transformed into the coordinate system of `relative` */
virtual Vec getRelativeOffset(Vec v, Widget *relative);
/** Returns `v` transformed into world coordinates */
Vec getAbsoluteOffset(Vec v) {
return getRelativeOffset(v, NULL);
}
/** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */
virtual Rect getViewport(Rect r);

@@ -149,6 +154,7 @@ struct TransformWidget : Widget {

struct ZoomWidget : Widget {
float zoom = 1.0;
Vec getRelativeOffset(Vec v, Widget *relative) override;
Rect getViewport(Rect r) override;
void setZoom(float zoom);
void draw(NVGcontext *vg) override;
@@ -230,6 +236,10 @@ Events are not passed to the underlying scene.
struct FramebufferWidget : virtual Widget {
/** Set this to true to re-render the children to the framebuffer the next time it is drawn */
bool dirty = true;
/** A margin in pixels around the children in the framebuffer
This prevents cutting the rendered SVG off on the box edges.
*/
float oversample;
/** The root object in the framebuffer scene
The FramebufferWidget owns the pointer
*/


+ 3
- 1
src/app.cpp View File

@@ -14,10 +14,12 @@ std::string gApiHost = "http://api.vcvrack.com";

RackWidget *gRackWidget = NULL;
Toolbar *gToolbar = NULL;
RackScene *gRackScene = NULL;


void sceneInit() {
gScene = new RackScene();
gRackScene = new RackScene();
gScene = gRackScene;
}

void sceneDestroy() {


+ 0
- 3
src/app/RackScene.cpp View File

@@ -62,9 +62,6 @@ void RackScene::step() {
.plus(Vec(500, 500))
.div(zoomWidget->zoom);

// Set zoom from the toolbar's zoom slider
zoomWidget->setZoom(gToolbar->zoomSlider->value / 100.0);

Scene::step();

zoomWidget->box.size = gRackWidget->box.size.mult(zoomWidget->zoom);


+ 1
- 1
src/app/RackScrollWidget.cpp View File

@@ -6,7 +6,7 @@ namespace rack {


void RackScrollWidget::step() {
Vec pos = gMousePos.minus(getAbsolutePos());
Vec pos = gRackWidget->lastMousePos;
// Scroll rack if dragging cable near the edge of the screen
if (gRackWidget->wireContainer->activeWire) {
float margin = 20.0;


+ 1
- 0
src/app/RackWidget.cpp View File

@@ -17,6 +17,7 @@ namespace rack {
RackWidget::RackWidget() {
rails = new FramebufferWidget();
rails->box.size = Vec();
rails->oversample = 1.0;
{
RackRail *rail = new RackRail();
rail->box.size = Vec();


+ 8
- 0
src/app/SVGPanel.cpp View File

@@ -1,4 +1,5 @@
#include "app.hpp"
#include "gui.hpp"


namespace rack {
@@ -16,6 +17,13 @@ struct PanelBorder : TransparentWidget {
};


void SVGPanel::step() {
if (nearf(gPixelRatio, 1.0)) {
oversample = 2.0;
}
FramebufferWidget::step();
}

void SVGPanel::setBackground(std::shared_ptr<SVG> svg) {
clearChildren();



+ 10
- 4
src/app/Toolbar.cpp View File

@@ -39,7 +39,7 @@ struct QuitItem : MenuItem {
struct FileChoice : ChoiceButton {
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

{
@@ -70,7 +70,7 @@ struct SampleRateItem : MenuItem {
struct SampleRateChoice : ChoiceButton {
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y));
menu->box.size.x = box.size.x;

PauseItem *pauseItem = new PauseItem();
@@ -148,12 +148,18 @@ Toolbar::Toolbar() {

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.size.x = 150;
zoomSlider->label = "Zoom";
zoomSlider->unit = "%";
zoomSlider->setLimits(33.33, 200.0);
zoomSlider->setLimits(25.0, 200.0);
zoomSlider->setDefaultValue(100.0);
addChild(zoomSlider);
xPos += zoomSlider->box.size.x;


+ 4
- 8
src/app/WireWidget.cpp View File

@@ -124,31 +124,27 @@ void WireWidget::updateWire() {
}

Vec WireWidget::getOutputPos() {
Vec pos;
if (outputPort) {
pos = Rect(outputPort->getAbsolutePos(), outputPort->box.size).getCenter();
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gRackWidget);
}
else if (hoveredOutputPort) {
pos = Rect(hoveredOutputPort->getAbsolutePos(), hoveredOutputPort->box.size).getCenter();
return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), gRackWidget);
}
else {
return gRackWidget->lastMousePos;
}
return pos.minus(getAbsolutePos().minus(box.pos));
}

Vec WireWidget::getInputPos() {
Vec pos;
if (inputPort) {
pos = Rect(inputPort->getAbsolutePos(), inputPort->box.size).getCenter();
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gRackWidget);
}
else if (hoveredInputPort) {
pos = Rect(hoveredInputPort->getAbsolutePos(), hoveredInputPort->box.size).getCenter();
return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), gRackWidget);
}
else {
return gRackWidget->lastMousePos;
}
return pos.minus(getAbsolutePos().minus(box.pos));
}

void WireWidget::draw(NVGcontext *vg) {


+ 3
- 3
src/core/AudioInterface.cpp View File

@@ -335,7 +335,7 @@ struct AudioChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

int deviceCount = audioInterface->getDeviceCount();
@@ -373,7 +373,7 @@ struct SampleRateChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

const float sampleRates[6] = {44100, 48000, 88200, 96000, 176400, 192000};
@@ -404,7 +404,7 @@ struct BlockSizeChoice : ChoiceButton {
AudioInterface *audioInterface;
void onAction() override {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

const int blockSizes[] = {64, 128, 256, 512, 1024, 2048, 4096};


+ 1
- 1
src/core/MidiClockToCV.cpp View File

@@ -205,7 +205,7 @@ struct ClockRatioChoice : ChoiceButton {

void onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

for (unsigned long ratio = 0; ratio < ratioNames.size(); ratio++) {


+ 2
- 2
src/core/MidiIO.cpp View File

@@ -181,7 +181,7 @@ void MidiItem::onAction() {

void MidiChoice::onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

{
@@ -216,7 +216,7 @@ void ChannelItem::onAction() {

void ChannelChoice::onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

{


+ 1
- 1
src/core/QuadMidiToCV.cpp View File

@@ -256,7 +256,7 @@ struct ModeChoice : ChoiceButton {

void onAction() {
Menu *menu = gScene->createMenu();
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y));
menu->box.pos = getAbsoluteOffset(Vec(0, box.size.y)).round();
menu->box.size.x = box.size.x;

for (unsigned long i = 0; i < modeNames.size(); i++) {


+ 2
- 2
src/engine.cpp View File

@@ -33,8 +33,8 @@ static int smoothParamId;
static float smoothValue;


void Light::setSmooth(float v) {
value += (v - value) / sampleRate * 60.0;
void Light::setBrightnessSmooth(float brightness) {
value += (powf(brightness, 2) - value) / sampleRate * 60.0;
}




+ 9
- 5
src/gui.cpp View File

@@ -218,9 +218,6 @@ void errorCallback(int error, const char *description) {
void renderGui() {
int width, height;
glfwGetFramebufferSize(gWindow, &width, &height);
int windowWidth, windowHeight;
glfwGetWindowSize(gWindow, &windowWidth, &windowHeight);
gPixelRatio = (float)width / windowWidth;

// Update and render
nvgBeginFrame(gVg, width, height, gPixelRatio);
@@ -257,7 +254,7 @@ void guiInit() {
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
gWindow = glfwCreateWindow(640, 480, "", NULL, NULL);
if (!gWindow) {
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Cannot open window with OpenGL 2.0 renderer. Does your graphics card support OpenGL 2.0 or greater? If so, are the latest drivers installed?");
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Cannot open window with OpenGL 2.0 renderer. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed.");
exit(1);
}

@@ -277,7 +274,7 @@ void guiInit() {
glewExperimental = GL_TRUE;
err = glewInit();
if (err != GLEW_OK) {
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize GLEW. Does your graphics card support OpenGL 2.0 or greater? If so, are the latest drivers installed?");
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize GLEW. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed.");
exit(1);
}

@@ -341,6 +338,13 @@ void guiRun() {
}
glfwSetWindowTitle(gWindow, title.c_str());

// Get framebuffer size
int width, height;
glfwGetFramebufferSize(gWindow, &width, &height);
int windowWidth, windowHeight;
glfwGetWindowSize(gWindow, &windowWidth, &windowHeight);
gPixelRatio = (float)width / windowWidth;

// Step scene
gScene->step();



+ 5
- 3
src/settings.cpp View File

@@ -28,7 +28,7 @@ static json_t *settingsToJson() {
json_object_set_new(rootJ, "wireTension", tensionJ);

// zoom
float zoom = gToolbar->zoomSlider->value;
float zoom = gRackScene->zoomWidget->zoom;
json_t *zoomJ = json_real(zoom);
json_object_set_new(rootJ, "zoom", zoomJ);

@@ -69,8 +69,10 @@ static void settingsFromJson(json_t *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
json_t *allowCursorLockJ = json_object_get(rootJ, "allowCursorLock");


+ 2
- 6
src/widgets/FramebufferWidget.cpp View File

@@ -9,12 +9,6 @@
namespace rack {


/** A margin in pixels around the children in the framebuffer
This prevents cutting the rendered SVG off on the box edges.
*/
static const float oversample = 2.0;


struct FramebufferWidget::Internal {
NVGLUframebuffer *fb = NULL;
Rect box;
@@ -31,6 +25,7 @@ struct FramebufferWidget::Internal {


FramebufferWidget::FramebufferWidget() {
oversample = 1.0;
internal = new Internal();
}

@@ -65,6 +60,7 @@ void FramebufferWidget::draw(NVGcontext *vg) {
if (fbSize.x <= 0.0 || fbSize.y <= 0.0)
return;

// printf("rendering framebuffer %f %f\n", fbSize.x, fbSize.y);
// 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.


+ 1
- 0
src/widgets/SVGWidget.cpp View File

@@ -201,6 +201,7 @@ void SVGWidget::wrap() {

void SVGWidget::draw(NVGcontext *vg) {
if (svg && svg->handle) {
// printf("drawing svg %f %f\n", box.size.x, box.size.y);
drawSVG(vg, svg->handle);
}
}


+ 2
- 0
src/widgets/Slider.cpp View File

@@ -23,11 +23,13 @@ void Slider::onDragMove(Vec mouseRel) {
void Slider::onDragEnd() {
state = BND_DEFAULT;
guiCursorUnlock();
onAction();
}

void Slider::onMouseDownOpaque(int button) {
if (button == 1) {
setValue(defaultValue);
onAction();
}
}



+ 1
- 1
src/widgets/Tooltip.cpp View File

@@ -6,7 +6,7 @@ namespace rack {

void Tooltip::step() {
// Follow the mouse
box.pos = gMousePos.minus(parent->getAbsolutePos());
box.pos = gMousePos;

// Wrap size to contents
// box.size = getChildrenBoundingBox().getBottomRight();


+ 17
- 17
src/widgets/Widget.cpp View File

@@ -16,28 +16,28 @@ Widget::~Widget() {
clearChildren();
}

Vec Widget::getAbsolutePos() {
// Recursively compute position offset from parents
if (!parent) {
return box.pos;
}
else {
return box.pos.plus(parent->getAbsolutePos());
Rect Widget::getChildrenBoundingBox() {
Rect bound;
for (Widget *child : children) {
if (child == children.front()) {
bound = child->box;
}
else {
bound = bound.expand(child->box);
}
}
return bound;
}

Rect Widget::getChildrenBoundingBox() {
if (children.empty()) {
return Rect();
Vec Widget::getRelativeOffset(Vec v, Widget *relative) {
if (this == relative) {
return v;
}

Vec topLeft = Vec(INFINITY, INFINITY);
Vec bottomRight = Vec(-INFINITY, -INFINITY);
for (Widget *child : children) {
topLeft = topLeft.min(child->box.pos);
bottomRight = bottomRight.max(child->box.getBottomRight());
v = v.plus(box.pos);
if (parent) {
v = parent->getRelativeOffset(v, relative);
}
return Rect(topLeft, bottomRight.minus(topLeft));
return v;
}

Rect Widget::getViewport(Rect r) {


+ 5
- 0
src/widgets/ZoomWidget.cpp View File

@@ -3,6 +3,11 @@

namespace rack {


Vec ZoomWidget::getRelativeOffset(Vec v, Widget *relative) {
return Widget::getRelativeOffset(v.mult(zoom), relative);
}

Rect ZoomWidget::getViewport(Rect r) {
r.pos = r.pos.mult(zoom);
r.size = r.size.mult(zoom);


Loading…
Cancel
Save