@@ -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" | |||