| @@ -24,6 +24,11 @@ | |||
| #define ICON_LOGIN 0xE740 | |||
| #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 | |||
| 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); | |||
| } | |||
| 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) | |||
| { | |||
| 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; | |||
| int i; | |||
| 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); | |||
| // 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); | |||
| nvgTranslate(vg, 0, -(stackh - h)*u); | |||
| dv = 1.0f / (float)(nimages-1); | |||
| for (i = 0; i < nimages; i++) { | |||
| float tx, ty; | |||
| float tx, ty, v, a; | |||
| tx = x+10; | |||
| ty = y+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; | |||
| 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); | |||
| nvgRoundedRect(vg, tx,ty, thumb,thumb, 5); | |||
| nvgFillPaint(vg, imgPaint); | |||
| @@ -819,6 +860,7 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h | |||
| float lineh; | |||
| float caretx, px; | |||
| float bounds[4]; | |||
| float a; | |||
| float gx,gy; | |||
| int gutter = 0; | |||
| NVG_NOTUSED(height); | |||
| @@ -900,6 +942,14 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h | |||
| nvgTextLineHeight(vg, 1.2f); | |||
| 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); | |||
| 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); | |||
| @@ -179,7 +179,7 @@ int main() | |||
| renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); | |||
| 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); | |||
| nvgTranslate(vg, 540, 300); | |||
| nvgRect(vg, 0, 0, 150, 150); | |||
| @@ -59,6 +59,7 @@ struct NVGstate { | |||
| float miterLimit; | |||
| int lineJoin; | |||
| int lineCap; | |||
| float alpha; | |||
| float xform[6]; | |||
| struct NVGscissor scissor; | |||
| float fontSize; | |||
| @@ -519,6 +520,7 @@ void nvgReset(struct NVGcontext* ctx) | |||
| state->miterLimit = 10.0f; | |||
| state->lineCap = NVG_BUTT; | |||
| state->lineJoin = NVG_MITER; | |||
| state->alpha = 1.0f; | |||
| nvgTransformIdentity(state->xform); | |||
| state->scissor.extent[0] = 0.0f; | |||
| @@ -557,6 +559,11 @@ void nvgLineJoin(struct NVGcontext* ctx, int 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) | |||
| { | |||
| @@ -786,7 +793,7 @@ struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, | |||
| struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, | |||
| float cx, float cy, float w, float h, float angle, | |||
| int image, int repeat) | |||
| int image, int repeat, float alpha) | |||
| { | |||
| struct NVGpaint p; | |||
| NVG_NOTUSED(ctx); | |||
| @@ -802,6 +809,8 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, | |||
| p.image = image; | |||
| p.repeat = repeat; | |||
| p.innerColor = p.outerColor = nvgRGBAf(1,1,1,alpha); | |||
| return p; | |||
| } | |||
| @@ -1981,6 +1990,7 @@ void nvgFill(struct NVGcontext* ctx) | |||
| { | |||
| struct NVGstate* state = nvg__getState(ctx); | |||
| const struct NVGpath* path; | |||
| struct NVGpaint fillPaint = state->fill; | |||
| int i; | |||
| nvg__flattenPaths(ctx); | |||
| @@ -1989,7 +1999,11 @@ void nvgFill(struct NVGcontext* ctx) | |||
| else | |||
| 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); | |||
| // Count triangles | |||
| @@ -2019,6 +2033,10 @@ void nvgStroke(struct NVGcontext* ctx) | |||
| strokeWidth = ctx->fringeWidth; | |||
| } | |||
| // Apply global alpha | |||
| strokePaint.innerColor.a *= state->alpha; | |||
| strokePaint.outerColor.a *= state->alpha; | |||
| nvg__flattenPaths(ctx); | |||
| if (ctx->params.edgeAntiAlias) | |||
| @@ -2171,6 +2189,11 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons | |||
| // Render triangles. | |||
| paint = state->fill; | |||
| 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->drawCallCount++; | |||
| @@ -66,6 +66,7 @@ enum NVGlineCap { | |||
| }; | |||
| enum NVGpatternRepeat { | |||
| NVG_NOREPEAT = 0, | |||
| NVG_REPEATX = 0x01, // Repeat image pattern in X 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. | |||
| 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 | |||
| // | |||
| @@ -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. | |||
| // 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, | |||
| float angle, int image, int repeat); | |||
| float angle, int image, int repeat, float alpha); | |||
| // | |||
| // Scissoring | |||
| @@ -524,6 +524,8 @@ static int glnvg__renderCreate(void* uptr) | |||
| " vec4 color = texture2D(tex, pt);\n" | |||
| "#endif\n" | |||
| " color = texType == 0 ? color : vec4(1,1,1,color.x);\n" | |||
| " // Apply color tint and alpha.\n" | |||
| " color *= innerCol;\n" | |||
| " // Combine alpha\n" | |||
| " color.w *= strokeAlpha * scissor;\n" | |||
| " result = color;\n" | |||