Browse Source

Fix Light when transparency is used, added preliminary ZoomWidget functionality to RackScene, added experimental linear gradients to SVGWidget, added sticky mouse button to gui.cpp, fix math in ScrollBar

tags/v0.4.0
Andrew Belt 7 years ago
parent
commit
4cf19e112b
12 changed files with 136 additions and 69 deletions
  1. +3
    -1
      include/app.hpp
  2. +11
    -2
      include/components.hpp
  3. +15
    -10
      res/ComponentLibrary/PB61303_0.svg
  4. +13
    -8
      res/ComponentLibrary/PB61303_1.svg
  5. +4
    -3
      src/app/Light.cpp
  6. +22
    -12
      src/app/RackScene.cpp
  7. +3
    -5
      src/app/RackWidget.cpp
  8. +1
    -1
      src/app/SVGSwitch.cpp
  9. +1
    -1
      src/app/WireWidget.cpp
  10. +25
    -1
      src/gui.cpp
  11. +32
    -19
      src/widgets/SVGWidget.cpp
  12. +6
    -6
      src/widgets/ScrollBar.cpp

+ 3
- 1
include/app.hpp View File

@@ -157,7 +157,8 @@ struct CircularShadow : TransparentWidget {
};

struct Light : TransparentWidget {
NVGcolor color;
NVGcolor bgColor = nvgRGBf(0, 0, 0);
NVGcolor color = nvgRGBf(1, 1, 1);
void draw(NVGcontext *vg);
};

@@ -321,6 +322,7 @@ struct PluginManagerWidget : Widget {
struct RackScene : Scene {
Toolbar *toolbar;
ScrollWidget *scrollWidget;
ZoomWidget *zoomWidget;

RackScene();
void step();


+ 11
- 2
include/components.hpp View File

@@ -402,7 +402,7 @@ struct ColorValueLight : ValueLight {
void setValue(float v) {
v = sqrtBipolar(v);
color = baseColor;
color.a = clampf(v, 0.0, 1.0);
color.a = clampf(v * baseColor.a, 0.0, 1.0);
}
};

@@ -430,7 +430,7 @@ struct PolarityLight : ValueLight {
void setValue(float v) {
v = sqrtBipolar(v);
color = (v >= 0.0) ? posColor : negColor;
color.a = clampf(fabsf(v), 0.0, 1.0);
color.a = clampf(fabsf(v) * color.a, 0.0, 1.0);
}
};

@@ -548,6 +548,15 @@ struct BefacoPush : SVGSwitch, MomentarySwitch {
}
};

struct PB61303 : SVGSwitch, MomentarySwitch {
PB61303() {
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/PB61303_0.svg")));
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/PB61303_1.svg")));
sw->wrap();
box.size = sw->box.size;
}
};


////////////////////
// Misc


+ 15
- 10
res/ComponentLibrary/PB61303_0.svg View File

@@ -160,7 +160,7 @@
x2="87.030029"
y2="73.994049"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-90,83.154938,73.994048)" />
gradientTransform="matrix(0,-0.93432349,0.93432349,0,14.020561,151.68766)" />
</defs>
<sodipodi:namedview
id="base"
@@ -169,12 +169,12 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="22.964109"
inkscape:cy="8.9651844"
inkscape:zoom="22.4"
inkscape:cx="22.801127"
inkscape:cy="13.743925"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:current-layer="g19440"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
@@ -186,7 +186,12 @@
inkscape:window-maximized="0"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true" />
inkscape:bbox-nodes="true"
inkscape:object-nodes="false">
<inkscape:grid
type="xygrid"
id="grid20375" />
</sodipodi:namedview>
<metadata
id="metadata18402">
<rdf:RDF>
@@ -195,7 +200,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -217,12 +222,12 @@
inkscape:connector-curvature="0"
id="path17974"
style="fill:#6b6969;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.45976272"
d="m 87.654936,73.994048 c 0,2.484967 -2.014361,4.49968 -4.500033,4.49968 -2.485672,0 -4.500033,-2.014713 -4.500033,-4.49968 0,-2.484967 2.014361,-4.49968 4.500033,-4.49968 2.485672,0 4.500033,2.014713 4.500033,4.49968" />
d="m 87.465003,73.994048 c 0,2.380367 -1.929341,4.310275 -4.3101,4.310275 -2.380759,0 -4.310099,-1.929908 -4.310099,-4.310275 0,-2.380367 1.92934,-4.310275 4.310099,-4.310275 2.380759,0 4.3101,1.929908 4.3101,4.310275" />
<path
inkscape:connector-curvature="0"
id="path18024"
style="fill:url(#linearGradient19435);fill-opacity:1;stroke:none;stroke-width:0.45976272"
d="m 79.280028,73.994224 c 0,2.140303 1.735314,3.874911 3.87491,3.874911 2.139597,0 3.874911,-1.734608 3.874911,-3.874911 0,-2.140656 -1.735314,-3.875264 -3.874911,-3.875264 -2.139596,0 -3.87491,1.734608 -3.87491,3.875264 m 0.176389,0 c 0,-2.039761 1.659114,-3.698875 3.698521,-3.698875 2.039408,0 3.698522,1.659114 3.698522,3.698875 0,2.039408 -1.659114,3.698522 -3.698522,3.698522 -2.039407,0 -3.698521,-1.659114 -3.698521,-3.698522" />
d="m 79.534519,73.994213 c 0,1.999735 1.621344,3.62042 3.620419,3.62042 1.999076,0 3.620421,-1.620685 3.620421,-3.62042 0,-2.000066 -1.621345,-3.620751 -3.620421,-3.620751 -1.999075,0 -3.620419,1.620685 -3.620419,3.620751 m 0.164804,0 c 0,-1.905797 1.550149,-3.455946 3.455615,-3.455946 1.905467,0 3.455616,1.550149 3.455616,3.455946 0,1.905466 -1.550149,3.455615 -3.455616,3.455615 -1.905466,0 -3.455615,-1.550149 -3.455615,-3.455615" />
</g>
</g>
</svg>

+ 13
- 8
res/ComponentLibrary/PB61303_1.svg View File

@@ -160,7 +160,7 @@
x2="87.030029"
y2="73.994049"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-90,83.154938,73.994048)" />
gradientTransform="matrix(0,-0.93432349,0.93432349,0,14.020561,151.68766)" />
</defs>
<sodipodi:namedview
id="base"
@@ -169,12 +169,12 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="22.964109"
inkscape:cy="8.9651844"
inkscape:zoom="22.4"
inkscape:cx="22.801127"
inkscape:cy="13.743925"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
@@ -186,7 +186,12 @@
inkscape:window-maximized="0"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true" />
inkscape:bbox-nodes="true"
inkscape:object-nodes="false">
<inkscape:grid
type="xygrid"
id="grid20375" />
</sodipodi:namedview>
<metadata
id="metadata18402">
<rdf:RDF>
@@ -217,12 +222,12 @@
inkscape:connector-curvature="0"
id="path17974"
style="fill:#6b6969;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.45976272"
d="m 87.654936,73.994048 c 0,2.484967 -2.014361,4.49968 -4.500033,4.49968 -2.485672,0 -4.500033,-2.014713 -4.500033,-4.49968 0,-2.484967 2.014361,-4.49968 4.500033,-4.49968 2.485672,0 4.500033,2.014713 4.500033,4.49968" />
d="m 87.465003,73.994048 c 0,2.380367 -1.929341,4.310275 -4.3101,4.310275 -2.380759,0 -4.310099,-1.929908 -4.310099,-4.310275 0,-2.380367 1.92934,-4.310275 4.310099,-4.310275 2.380759,0 4.3101,1.929908 4.3101,4.310275" />
<path
inkscape:connector-curvature="0"
id="path18024"
style="fill:url(#linearGradient19435);fill-opacity:1;stroke:none;stroke-width:0.45976272"
d="m 79.280028,73.994224 c 0,2.140303 1.735314,3.874911 3.87491,3.874911 2.139597,0 3.874911,-1.734608 3.874911,-3.874911 0,-2.140656 -1.735314,-3.875264 -3.874911,-3.875264 -2.139596,0 -3.87491,1.734608 -3.87491,3.875264 m 0.176389,0 c 0,-2.039761 1.659114,-3.698875 3.698521,-3.698875 2.039408,0 3.698522,1.659114 3.698522,3.698875 0,2.039408 -1.659114,3.698522 -3.698522,3.698522 -2.039407,0 -3.698521,-1.659114 -3.698521,-3.698522" />
d="m 79.534519,73.994213 c 0,1.999735 1.621344,3.62042 3.620419,3.62042 1.999076,0 3.620421,-1.620685 3.620421,-3.62042 0,-2.000066 -1.621345,-3.620751 -3.620421,-3.620751 -1.999075,0 -3.620419,1.620685 -3.620419,3.620751 m 0.164804,0 c 0,-1.905797 1.550149,-3.455946 3.455615,-3.455946 1.905467,0 3.455616,1.550149 3.455616,3.455946 0,1.905466 -1.550149,3.455615 -3.455616,3.455615 -1.905466,0 -3.455615,-1.550149 -3.455615,-3.455615" />
</g>
</g>
</svg>

+ 4
- 3
src/app/Light.cpp View File

@@ -5,8 +5,7 @@ namespace rack {


void Light::draw(NVGcontext *vg) {
NVGcolor bgColor = nvgRGBf(0.0, 0.0, 0.0);
float radius = roundf(box.size.x / 2.0);
float radius = box.size.x / 2.0;
float oradius = radius + 30.0;

// Solid
@@ -17,7 +16,9 @@ void Light::draw(NVGcontext *vg) {

// Border
nvgStrokeWidth(vg, 1.0);
nvgStrokeColor(vg, nvgTransRGBAf(bgColor, 0.5));
NVGcolor borderColor = bgColor;
borderColor.a *= 0.5;
nvgStrokeColor(vg, borderColor);
nvgStroke(vg);

// Inner glow


+ 22
- 12
src/app/RackScene.cpp View File

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


static std::string versionMessage = "";
static std::string newVersion = "";

static void checkVersion() {
json_t *resJ = requestJson(METHOD_GET, gApiHost + "/version", NULL);
@@ -18,7 +18,7 @@ static void checkVersion() {
if (versionJ) {
const char *version = json_string_value(versionJ);
if (version && version != gApplicationVersion) {
versionMessage = stringf("Rack %s is available.\n\nYou have Rack %s.\n\nWould you like to download the new version on the website?", version, gApplicationVersion.c_str());
newVersion = version;
}
}
json_decref(resJ);
@@ -29,14 +29,14 @@ static void checkVersion() {
RackScene::RackScene() {
scrollWidget = new ScrollWidget();
{
// ZoomWidget *zoomWidget = new ZoomWidget();
// zoomWidget->zoom = 0.8;
// scrollWidget->container->addChild(zoomWidget);
assert(!gRackWidget);
gRackWidget = new RackWidget();
scrollWidget->container->addChild(gRackWidget);
// zoomWidget->addChild(gRackWidget);
zoomWidget = new ZoomWidget();
zoomWidget->zoom = 1.0;
{
assert(!gRackWidget);
gRackWidget = new RackWidget();
zoomWidget->addChild(gRackWidget);
}
scrollWidget->container->addChild(zoomWidget);
}
addChild(scrollWidget);

@@ -52,19 +52,29 @@ RackScene::RackScene() {
}

void RackScene::step() {
// Resize owned descendants
toolbar->box.size.x = box.size.x;
scrollWidget->box.size = box.size.minus(scrollWidget->box.pos);

// Resize to be a bit larger than the ScrollWidget viewport
gRackWidget->box.size = scrollWidget->box.size
.minus(scrollWidget->container->box.pos)
.plus(Vec(500, 500))
.div(zoomWidget->zoom);

Scene::step();

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

// Version popup message
if (!versionMessage.empty()) {
if (!newVersion.empty()) {
std::string versionMessage = stringf("Rack %s is available.\n\nYou have Rack %s.\n\nWould you like to download the new version on the website?", newVersion, gApplicationVersion.c_str());
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, versionMessage.c_str())) {
std::thread t(openBrowser, "https://vcvrack.com/");
t.detach();
guiClose();
}
versionMessage = "";
newVersion = "";
}
}



+ 3
- 5
src/app/RackWidget.cpp View File

@@ -304,12 +304,10 @@ void RackWidget::repositionModule(ModuleWidget *m) {
void RackWidget::step() {
rails->step();

// Resize to be a bit larger than the ScrollWidget viewport
assert(parent);
assert(parent->parent);
// Expand size to fit modules
Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight();
Vec viewportSize = parent->parent->box.size.minus(parent->box.pos);
box.size = moduleSize.max(viewportSize).plus(Vec(500, 500));
// We assume that the size is reset by a parent before calling step(). Otherwise it will grow unbounded.
box.size = box.size.max(moduleSize);

// Reposition modules
for (Widget *child : moduleContainer->children) {


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

@@ -26,7 +26,7 @@ void SVGSwitch::onChange() {
if (0 <= index && index < (int)frames.size())
sw->svg = frames[index];
dirty = true;
ParamWidget::onChange();
Switch::onChange();
}




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

@@ -172,7 +172,7 @@ void WireWidget::drawPlugs(NVGcontext *vg) {
Vec outputPos = getOutputPos();
Vec inputPos = getInputPos();
drawPlug(vg, outputPos, color);
drawPlug(vg, getInputPos(), color);
drawPlug(vg, inputPos, color);

// Draw plug light
/*


+ 25
- 1
src/gui.cpp View File

@@ -1,4 +1,5 @@
#include <map>
#include <queue>

#include "gui.hpp"
#include "app.hpp"
@@ -87,6 +88,28 @@ void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods) {
}
}

struct MouseButtonArguments {
GLFWwindow *window;
int button;
int action;
int mods;
};

static std::queue<MouseButtonArguments> mouseButtonQueue;
void mouseButtonStickyPop() {
if (!mouseButtonQueue.empty()) {
MouseButtonArguments args = mouseButtonQueue.front();
mouseButtonQueue.pop();
mouseButtonCallback(args.window, args.button, args.action, args.mods);
}
}

void mouseButtonStickyCallback(GLFWwindow *window, int button, int action, int mods) {
// Defer multiple clicks per frame to future frames
MouseButtonArguments args = {window, button, action, mods};
mouseButtonQueue.push(args);
}

void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) {
Vec mousePos = Vec(xpos, ypos).round();
Vec mouseRel = mousePos.minus(gMousePos);
@@ -238,7 +261,7 @@ void guiInit() {
glfwSwapInterval(1);

glfwSetWindowSizeCallback(gWindow, windowSizeCallback);
glfwSetMouseButtonCallback(gWindow, mouseButtonCallback);
glfwSetMouseButtonCallback(gWindow, mouseButtonStickyCallback);
// glfwSetCursorPosCallback(gWindow, cursorPosCallback);
glfwSetCursorEnterCallback(gWindow, cursorEnterCallback);
glfwSetScrollCallback(gWindow, scrollCallback);
@@ -293,6 +316,7 @@ void guiRun() {
glfwGetCursorPos(gWindow, &xpos, &ypos);
cursorPosCallback(gWindow, xpos, ypos);
}
mouseButtonStickyPop();

// Set window title
std::string title = gApplicationName + " " + gApplicationVersion;


+ 32
- 19
src/widgets/SVGWidget.cpp View File

@@ -15,6 +15,31 @@ static NVGcolor getNVGColor(uint32_t color) {
(color >> 24) & 0xff);
}

static NVGpaint getPaint(NVGcontext *vg, NSVGpaint *p) {
assert(p->type == NSVG_PAINT_LINEAR_GRADIENT || p->type == NSVG_PAINT_RADIAL_GRADIENT);
NSVGgradient *g = p->gradient;
assert(g->nstops >= 1);
NVGcolor icol = getNVGColor(g->stops[0].color);
NVGcolor ocol = getNVGColor(g->stops[g->nstops - 1].color);

float inverse[6];
nvgTransformInverse(inverse, g->xform);
DEBUG_ONLY(printf(" inverse: %f %f %f %f %f %f\n", inverse[0], inverse[1], inverse[2], inverse[3], inverse[4], inverse[5]);)
Vec s, e;
DEBUG_ONLY(printf(" sx: %f sy: %f ex: %f ey: %f\n", s.x, s.y, e.x, e.y);)
// Is it always the case that the gradient should be transformed from (0, 0) to (0, 1)?
nvgTransformPoint(&s.x, &s.y, inverse, 0, 0);
nvgTransformPoint(&e.x, &e.y, inverse, 0, 1);
DEBUG_ONLY(printf(" sx: %f sy: %f ex: %f ey: %f\n", s.x, s.y, e.x, e.y);)

NVGpaint paint;
if (p->type == NSVG_PAINT_LINEAR_GRADIENT)
paint = nvgLinearGradient(vg, s.x, s.y, e.x, e.y, icol, ocol);
else
paint = nvgRadialGradient(vg, s.x, s.y, 0.0, 160, icol, ocol);
return paint;
}

/** Returns the parameterized value of the line p2--p3 where it intersects with p0--p1 */
static float getLineCrossing(Vec p0, Vec p1, Vec p2, Vec p3) {
Vec b = p2.minus(p0);
@@ -121,30 +146,15 @@ static void drawSVG(NVGcontext *vg, NSVGimage *svg) {
nvgFillColor(vg, color);
DEBUG_ONLY(printf(" fill color (%g, %g, %g, %g)\n", color.r, color.g, color.b, color.a);)
} break;
case NSVG_PAINT_LINEAR_GRADIENT: {
NSVGgradient *g = shape->fill.gradient;
(void)g;
DEBUG_ONLY(printf(" linear gradient: %f\t%f\n", g->fx, g->fy);)
} break;
case NSVG_PAINT_LINEAR_GRADIENT:
case NSVG_PAINT_RADIAL_GRADIENT: {
NSVGgradient *g = shape->fill.gradient;
DEBUG_ONLY(printf(" radial gradient: %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", g->fx, g->fy, g->xform[0], g->xform[1], g->xform[2], g->xform[3], g->xform[4], g->xform[5]);)
(void)g;
DEBUG_ONLY(printf(" gradient: type: %s xform: %f %f %f %f %f %f spread: %d fx: %f fy: %f nstops: %d\n", (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT ? "linear" : "radial"), g->xform[0], g->xform[1], g->xform[2], g->xform[3], g->xform[4], g->xform[5], g->spread, g->fx, g->fy, g->nstops);)
for (int i = 0; i < g->nstops; i++) {
DEBUG_ONLY(printf(" stop: #%08x\t%f\n", g->stops[i].color, g->stops[i].offset);)
}
assert(g->nstops >= 1);
NVGcolor color0 = getNVGColor(g->stops[0].color);
NVGcolor color1 = getNVGColor(g->stops[g->nstops - 1].color);

float inverse[6];
// Rect shapeBox = Rect::fromMinMax(Vec(shape->bounds[0], shape->bounds[1]), Vec(shape->bounds[2], shape->bounds[3]));
nvgTransformInverse(inverse, g->xform);
Vec c;
nvgTransformPoint(&c.x, &c.y, inverse, 5, 5);
printf("%f %f\n", c.x, c.y);

NVGpaint paint = nvgRadialGradient(vg, c.x, c.y, 0.0, 160, color0, color1);
nvgFillPaint(vg, paint);
nvgFillPaint(vg, getPaint(vg, &shape->fill));
} break;
}
nvgFill(vg);
@@ -171,6 +181,9 @@ static void drawSVG(NVGcontext *vg, NSVGimage *svg) {
}

nvgRestore(vg);

// if (std::string(shape->id) == "rect19347")
// exit(0);
}

DEBUG_ONLY(printf("\n");)


+ 6
- 6
src/widgets/ScrollBar.cpp View File

@@ -8,13 +8,13 @@ namespace rack {
void ScrollBar::draw(NVGcontext *vg) {
ScrollWidget *scrollWidget = dynamic_cast<ScrollWidget*>(parent);
assert(scrollWidget);
Vec containerCorner = scrollWidget->container->getChildrenBoundingBox().getBottomRight();
Vec viewportCorner = scrollWidget->container->getChildrenBoundingBox().getBottomRight();

float containerSize = (orientation == HORIZONTAL) ? containerCorner.x : containerCorner.y;
float boxSize = (orientation == HORIZONTAL) ? box.size.x : box.size.y;
float offset = (orientation == HORIZONTAL) ? scrollWidget->offset.x : scrollWidget->offset.y;
offset = offset / (containerSize - boxSize);
float size = boxSize / containerSize;
float viewportSize = (orientation == HORIZONTAL) ? viewportCorner.x : viewportCorner.y;
float containerSize = (orientation == HORIZONTAL) ? scrollWidget->box.size.x : scrollWidget->box.size.y;
float viewportOffset = (orientation == HORIZONTAL) ? scrollWidget->offset.x : scrollWidget->offset.y;
float offset = viewportOffset / (viewportSize - containerSize);
float size = containerSize / viewportSize;
size = clampf(size, 0.0, 1.0);
bndScrollBar(vg, 0.0, 0.0, box.size.x, box.size.y, state, offset, size);
}


Loading…
Cancel
Save