@@ -24,6 +24,11 @@ | |||||
#define ICON_LOGIN 0xE740 | #define ICON_LOGIN 0xE740 | ||||
#define ICON_TRASH 0xE729 | #define ICON_TRASH 0xE729 | ||||
static float minf(float a, float b) { return a < b ? a : b; } | |||||
static float maxf(float a, float b) { return a > b ? a : b; } | |||||
static float absf(float a) { return a >= 0.0f ? a : -a; } | |||||
static float clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } | |||||
// Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise | // Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise | ||||
int isBlack( struct NVGcolor col ) | int isBlack( struct NVGcolor col ) | ||||
{ | { | ||||
@@ -492,6 +497,32 @@ void drawGraph(struct NVGcontext* vg, float x, float y, float w, float h, float | |||||
nvgStrokeWidth(vg, 1.0f); | nvgStrokeWidth(vg, 1.0f); | ||||
} | } | ||||
void drawSpinner(struct NVGcontext* vg, float cx, float cy, float r, float t) | |||||
{ | |||||
float a0 = 0.0f + t*6; | |||||
float a1 = NVG_PI + t*6; | |||||
float r0 = r; | |||||
float r1 = r * 0.75f; | |||||
float ax,ay, bx,by; | |||||
struct NVGpaint paint; | |||||
nvgSave(vg); | |||||
nvgBeginPath(vg); | |||||
nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); | |||||
nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); | |||||
nvgClosePath(vg); | |||||
ax = cx + cosf(a0) * (r0+r1)*0.5f; | |||||
ay = cy + sinf(a0) * (r0+r1)*0.5f; | |||||
bx = cx + cosf(a1) * (r0+r1)*0.5f; | |||||
by = cy + sinf(a1) * (r0+r1)*0.5f; | |||||
paint = nvgLinearGradient(vg, ax,ay, bx,by, nvgRGBA(0,0,0,0), nvgRGBA(0,0,0,128)); | |||||
nvgFillPaint(vg, paint); | |||||
nvgFill(vg); | |||||
nvgRestore(vg); | |||||
} | |||||
void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, const int* images, int nimages, float t) | void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, const int* images, int nimages, float t) | ||||
{ | { | ||||
float cornerRadius = 3.0f; | float cornerRadius = 3.0f; | ||||
@@ -503,7 +534,8 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c | |||||
float stackh = (nimages/2) * (thumb+10) + 10; | float stackh = (nimages/2) * (thumb+10) + 10; | ||||
int i; | int i; | ||||
float u = (1+cosf(t*0.5f))*0.5f; | float u = (1+cosf(t*0.5f))*0.5f; | ||||
float scrollh; | |||||
float u2 = (1-cosf(t*0.2f))*0.5f; | |||||
float scrollh, dv; | |||||
nvgSave(vg); | nvgSave(vg); | ||||
// nvgClearState(vg); | // nvgClearState(vg); | ||||
@@ -530,8 +562,10 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c | |||||
nvgScissor(vg, x,y,w,h); | nvgScissor(vg, x,y,w,h); | ||||
nvgTranslate(vg, 0, -(stackh - h)*u); | nvgTranslate(vg, 0, -(stackh - h)*u); | ||||
dv = 1.0f / (float)(nimages-1); | |||||
for (i = 0; i < nimages; i++) { | for (i = 0; i < nimages; i++) { | ||||
float tx, ty; | |||||
float tx, ty, v, a; | |||||
tx = x+10; | tx = x+10; | ||||
ty = y+10; | ty = y+10; | ||||
tx += (i%2) * (thumb+10); | tx += (i%2) * (thumb+10); | ||||
@@ -548,7 +582,14 @@ void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, c | |||||
ix = -(iw-thumb)*0.5f; | ix = -(iw-thumb)*0.5f; | ||||
iy = 0; | iy = 0; | ||||
} | } | ||||
imgPaint = nvgImagePattern(vg, tx+ix, ty+iy, iw,ih, 0.0f/180.0f*NVG_PI, images[i], 0); | |||||
v = i * dv; | |||||
a = clampf((u2-v) / dv, 0, 1); | |||||
if (a < 1.0f) | |||||
drawSpinner(vg, tx+thumb/2,ty+thumb/2, thumb*0.25f, t); | |||||
imgPaint = nvgImagePattern(vg, tx+ix, ty+iy, iw,ih, 0.0f/180.0f*NVG_PI, images[i], NVG_NOREPEAT, a); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgRoundedRect(vg, tx,ty, thumb,thumb, 5); | nvgRoundedRect(vg, tx,ty, thumb,thumb, 5); | ||||
nvgFillPaint(vg, imgPaint); | nvgFillPaint(vg, imgPaint); | ||||
@@ -819,6 +860,7 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h | |||||
float lineh; | float lineh; | ||||
float caretx, px; | float caretx, px; | ||||
float bounds[4]; | float bounds[4]; | ||||
float a; | |||||
float gx,gy; | float gx,gy; | ||||
int gutter = 0; | int gutter = 0; | ||||
NVG_NOTUSED(height); | NVG_NOTUSED(height); | ||||
@@ -900,6 +942,14 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h | |||||
nvgTextLineHeight(vg, 1.2f); | nvgTextLineHeight(vg, 1.2f); | ||||
nvgTextBoxBounds(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL, bounds); | nvgTextBoxBounds(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL, bounds); | ||||
// Fade the tooltip out when close to it. | |||||
gx = fabsf((mx - (bounds[0]+bounds[2])*0.5f) / (bounds[0] - bounds[2])); | |||||
gy = fabsf((my - (bounds[1]+bounds[3])*0.5f) / (bounds[1] - bounds[3])); | |||||
a = maxf(gx, gy) - 0.5f; | |||||
a = clampf(a, 0, 1); | |||||
nvgGlobalAlpha(vg, a); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgFillColor(vg, nvgRGBA(220,220,220,255)); | nvgFillColor(vg, nvgRGBA(220,220,220,255)); | ||||
nvgRoundedRect(vg, bounds[0]-2,bounds[1]-2, (int)(bounds[2]-bounds[0])+4, (int)(bounds[3]-bounds[1])+4, 3); | nvgRoundedRect(vg, bounds[0]-2,bounds[1]-2, (int)(bounds[2]-bounds[0])+4, (int)(bounds[3]-bounds[1])+4, 3); | ||||
@@ -179,7 +179,7 @@ int main() | |||||
renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); | renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); | ||||
if (fb != NULL) { | if (fb != NULL) { | ||||
struct NVGpaint img = nvgImagePattern(vg, 0, 0, 150, 150, 0, fb->image, 0); | |||||
struct NVGpaint img = nvgImagePattern(vg, 0, 0, 150, 150, 0, fb->image, NVG_NOREPEAT, 1.0f); | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgTranslate(vg, 540, 300); | nvgTranslate(vg, 540, 300); | ||||
nvgRect(vg, 0, 0, 150, 150); | nvgRect(vg, 0, 0, 150, 150); | ||||
@@ -59,6 +59,7 @@ struct NVGstate { | |||||
float miterLimit; | float miterLimit; | ||||
int lineJoin; | int lineJoin; | ||||
int lineCap; | int lineCap; | ||||
float alpha; | |||||
float xform[6]; | float xform[6]; | ||||
struct NVGscissor scissor; | struct NVGscissor scissor; | ||||
float fontSize; | float fontSize; | ||||
@@ -519,6 +520,7 @@ void nvgReset(struct NVGcontext* ctx) | |||||
state->miterLimit = 10.0f; | state->miterLimit = 10.0f; | ||||
state->lineCap = NVG_BUTT; | state->lineCap = NVG_BUTT; | ||||
state->lineJoin = NVG_MITER; | state->lineJoin = NVG_MITER; | ||||
state->alpha = 1.0f; | |||||
nvgTransformIdentity(state->xform); | nvgTransformIdentity(state->xform); | ||||
state->scissor.extent[0] = 0.0f; | state->scissor.extent[0] = 0.0f; | ||||
@@ -557,6 +559,11 @@ void nvgLineJoin(struct NVGcontext* ctx, int join) | |||||
state->lineJoin = join; | state->lineJoin = join; | ||||
} | } | ||||
void nvgGlobalAlpha(struct NVGcontext* ctx, float alpha) | |||||
{ | |||||
struct NVGstate* state = nvg__getState(ctx); | |||||
state->alpha = alpha; | |||||
} | |||||
void nvgTransform(struct NVGcontext* ctx, float a, float b, float c, float d, float e, float f) | void nvgTransform(struct NVGcontext* ctx, float a, float b, float c, float d, float e, float f) | ||||
{ | { | ||||
@@ -786,7 +793,7 @@ struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, | |||||
struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, | struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, | ||||
float cx, float cy, float w, float h, float angle, | float cx, float cy, float w, float h, float angle, | ||||
int image, int repeat) | |||||
int image, int repeat, float alpha) | |||||
{ | { | ||||
struct NVGpaint p; | struct NVGpaint p; | ||||
NVG_NOTUSED(ctx); | NVG_NOTUSED(ctx); | ||||
@@ -802,6 +809,8 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, | |||||
p.image = image; | p.image = image; | ||||
p.repeat = repeat; | p.repeat = repeat; | ||||
p.innerColor = p.outerColor = nvgRGBAf(1,1,1,alpha); | |||||
return p; | return p; | ||||
} | } | ||||
@@ -1981,6 +1990,7 @@ void nvgFill(struct NVGcontext* ctx) | |||||
{ | { | ||||
struct NVGstate* state = nvg__getState(ctx); | struct NVGstate* state = nvg__getState(ctx); | ||||
const struct NVGpath* path; | const struct NVGpath* path; | ||||
struct NVGpaint fillPaint = state->fill; | |||||
int i; | int i; | ||||
nvg__flattenPaths(ctx); | nvg__flattenPaths(ctx); | ||||
@@ -1989,7 +1999,11 @@ void nvgFill(struct NVGcontext* ctx) | |||||
else | else | ||||
nvg__expandFill(ctx, 0.0f, NVG_MITER, 2.4f); | nvg__expandFill(ctx, 0.0f, NVG_MITER, 2.4f); | ||||
ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, ctx->fringeWidth, | |||||
// Apply global alpha | |||||
fillPaint.innerColor.a *= state->alpha; | |||||
fillPaint.outerColor.a *= state->alpha; | |||||
ctx->params.renderFill(ctx->params.userPtr, &fillPaint, &state->scissor, ctx->fringeWidth, | |||||
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); | ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); | ||||
// Count triangles | // Count triangles | ||||
@@ -2019,6 +2033,10 @@ void nvgStroke(struct NVGcontext* ctx) | |||||
strokeWidth = ctx->fringeWidth; | strokeWidth = ctx->fringeWidth; | ||||
} | } | ||||
// Apply global alpha | |||||
strokePaint.innerColor.a *= state->alpha; | |||||
strokePaint.outerColor.a *= state->alpha; | |||||
nvg__flattenPaths(ctx); | nvg__flattenPaths(ctx); | ||||
if (ctx->params.edgeAntiAlias) | if (ctx->params.edgeAntiAlias) | ||||
@@ -2171,6 +2189,11 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons | |||||
// Render triangles. | // Render triangles. | ||||
paint = state->fill; | paint = state->fill; | ||||
paint.image = ctx->fontImage; | paint.image = ctx->fontImage; | ||||
// Apply global alpha | |||||
paint.innerColor.a *= state->alpha; | |||||
paint.outerColor.a *= state->alpha; | |||||
ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts); | ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts); | ||||
ctx->drawCallCount++; | ctx->drawCallCount++; | ||||
@@ -66,6 +66,7 @@ enum NVGlineCap { | |||||
}; | }; | ||||
enum NVGpatternRepeat { | enum NVGpatternRepeat { | ||||
NVG_NOREPEAT = 0, | |||||
NVG_REPEATX = 0x01, // Repeat image pattern in X direction | NVG_REPEATX = 0x01, // Repeat image pattern in X direction | ||||
NVG_REPEATY = 0x02, // Repeat image pattern in Y direction | NVG_REPEATY = 0x02, // Repeat image pattern in Y direction | ||||
}; | }; | ||||
@@ -208,6 +209,10 @@ void nvgLineCap(struct NVGcontext* ctx, int cap); | |||||
// Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL. | // Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL. | ||||
void nvgLineJoin(struct NVGcontext* ctx, int join); | void nvgLineJoin(struct NVGcontext* ctx, int join); | ||||
// Sets the transparency applied to all rendered shapes. | |||||
// Alreade transparent paths will get proportionally more transparent as well. | |||||
void nvgGlobalAlpha(struct NVGcontext* ctx, float alpha); | |||||
// | // | ||||
// Transforms | // Transforms | ||||
// | // | ||||
@@ -354,7 +359,7 @@ struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, fl | |||||
// and repeat is combination of NVG_REPEATX and NVG_REPEATY which tells if the image should be repeated across x or y. | // and repeat is combination of NVG_REPEATX and NVG_REPEATY which tells if the image should be repeated across x or y. | ||||
// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). | // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). | ||||
struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, float ex, float ey, | struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, float ex, float ey, | ||||
float angle, int image, int repeat); | |||||
float angle, int image, int repeat, float alpha); | |||||
// | // | ||||
// Scissoring | // Scissoring | ||||
@@ -524,6 +524,8 @@ static int glnvg__renderCreate(void* uptr) | |||||
" vec4 color = texture2D(tex, pt);\n" | " vec4 color = texture2D(tex, pt);\n" | ||||
"#endif\n" | "#endif\n" | ||||
" color = texType == 0 ? color : vec4(1,1,1,color.x);\n" | " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" | ||||
" // Apply color tint and alpha.\n" | |||||
" color *= innerCol;\n" | |||||
" // Combine alpha\n" | " // Combine alpha\n" | ||||
" color.w *= strokeAlpha * scissor;\n" | " color.w *= strokeAlpha * scissor;\n" | ||||
" result = color;\n" | " result = color;\n" | ||||