void TextBox::draw(NVGcontext* ctx) { Widget::draw(ctx); NVGpaint bg = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, Color(255, 32), Color(32, 32)); NVGpaint fg1 = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, Color(150, 32), Color(32, 32)); NVGpaint fg2 = nvgBoxGradient(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3, 4, nvgRGBA(255, 0, 0, 100), nvgRGBA(255, 0, 0, 50)); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 1, mPos.y() + 1 + 1.0f, mSize.x() - 2, mSize.y() - 2, 3); if (mEditable && focused()) mValidFormat ? nvgFillPaint(ctx, fg1) : nvgFillPaint(ctx, fg2); else if (mSpinnable && mMouseDownPos.x() != -1) nvgFillPaint(ctx, fg1); else nvgFillPaint(ctx, bg); nvgFill(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x() + 0.5f, mPos.y() + 0.5f, mSize.x() - 1, mSize.y() - 1, 2.5f); nvgStrokeColor(ctx, Color(0, 48)); nvgStroke(ctx); nvgFontSize(ctx, fontSize()); nvgFontFace(ctx, "sans"); Vector2i drawPos(mPos.x(), mPos.y() + mSize.y() * 0.5f + 1); float xSpacing = mSize.y() * 0.3f; float unitWidth = 0; if (mUnitsImage > 0) { int w, h; nvgImageSize(ctx, mUnitsImage, &w, &h); float unitHeight = mSize.y() * 0.4f; unitWidth = w * unitHeight / h; NVGpaint imgPaint = nvgImagePattern( ctx, mPos.x() + mSize.x() - xSpacing - unitWidth, drawPos.y() - unitHeight * 0.5f, unitWidth, unitHeight, 0, mUnitsImage, mEnabled ? 0.7f : 0.35f); nvgBeginPath(ctx); nvgRect(ctx, mPos.x() + mSize.x() - xSpacing - unitWidth, drawPos.y() - unitHeight * 0.5f, unitWidth, unitHeight); nvgFillPaint(ctx, imgPaint); nvgFill(ctx); unitWidth += 2; } else if (!mUnits.empty()) { unitWidth = nvgTextBounds(ctx, 0, 0, mUnits.c_str(), nullptr, nullptr); nvgFillColor(ctx, Color(255, mEnabled ? 64 : 32)); nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE); nvgText(ctx, mPos.x() + mSize.x() - xSpacing, drawPos.y(), mUnits.c_str(), nullptr); unitWidth += 2; } float spinArrowsWidth = 0.f; if (mSpinnable && !focused()) { spinArrowsWidth = 14.f; nvgFontFace(ctx, "icons"); nvgFontSize(ctx, ((mFontSize < 0) ? mTheme->mButtonFontSize : mFontSize) * 1.2f); bool spinning = mMouseDownPos.x() != -1; { bool hover = mMouseFocus && spinArea(mMousePos) == SpinArea::Top; nvgFillColor(ctx, (mEnabled && (hover || spinning)) ? mTheme->mTextColor : mTheme->mDisabledTextColor); auto icon = utf8(ENTYPO_ICON_CHEVRON_UP); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); Vector2f iconPos(mPos.x() + 4.f, mPos.y() + mSize.y()/2.f - xSpacing/2.f); nvgText(ctx, iconPos.x(), iconPos.y(), icon.data(), nullptr); } { bool hover = mMouseFocus && spinArea(mMousePos) == SpinArea::Bottom; nvgFillColor(ctx, (mEnabled && (hover || spinning)) ? mTheme->mTextColor : mTheme->mDisabledTextColor); auto icon = utf8(ENTYPO_ICON_CHEVRON_DOWN); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); Vector2f iconPos(mPos.x() + 4.f, mPos.y() + mSize.y()/2.f + xSpacing/2.f + 1.5f); nvgText(ctx, iconPos.x(), iconPos.y(), icon.data(), nullptr); } nvgFontSize(ctx, fontSize()); nvgFontFace(ctx, "sans"); } switch (mAlignment) { case Alignment::Left: nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); drawPos.x() += xSpacing + spinArrowsWidth; break; case Alignment::Right: nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE); drawPos.x() += mSize.x() - unitWidth - xSpacing; break; case Alignment::Center: nvgTextAlign(ctx, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); drawPos.x() += mSize.x() * 0.5f; break; } nvgFontSize(ctx, fontSize()); nvgFillColor(ctx, mEnabled ? mTheme->mTextColor : mTheme->mDisabledTextColor); // clip visible text area float clipX = mPos.x() + xSpacing + spinArrowsWidth - 1.0f; float clipY = mPos.y() + 1.0f; float clipWidth = mSize.x() - unitWidth - spinArrowsWidth - 2 * xSpacing + 2.0f; float clipHeight = mSize.y() - 3.0f; nvgSave(ctx); nvgIntersectScissor(ctx, clipX, clipY, clipWidth, clipHeight); Vector2i oldDrawPos(drawPos); drawPos.x() += mTextOffset; if (mCommitted) { nvgText(ctx, drawPos.x(), drawPos.y(), mValue.c_str(), nullptr); } else { const int maxGlyphs = 1024; NVGglyphPosition glyphs[maxGlyphs]; float textBound[4]; nvgTextBounds(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, textBound); float lineh = textBound[3] - textBound[1]; // find cursor positions int nglyphs = nvgTextGlyphPositions(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, glyphs, maxGlyphs); updateCursor(ctx, textBound[2], glyphs, nglyphs); // compute text offset int prevCPos = mCursorPos > 0 ? mCursorPos - 1 : 0; int nextCPos = mCursorPos < nglyphs ? mCursorPos + 1 : nglyphs; float prevCX = cursorIndex2Position(prevCPos, textBound[2], glyphs, nglyphs); float nextCX = cursorIndex2Position(nextCPos, textBound[2], glyphs, nglyphs); if (nextCX > clipX + clipWidth) mTextOffset -= nextCX - (clipX + clipWidth) + 1; if (prevCX < clipX) mTextOffset += clipX - prevCX + 1; drawPos.x() = oldDrawPos.x() + mTextOffset; // draw text with offset nvgText(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr); nvgTextBounds(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, textBound); // recompute cursor positions nglyphs = nvgTextGlyphPositions(ctx, drawPos.x(), drawPos.y(), mValueTemp.c_str(), nullptr, glyphs, maxGlyphs); if (mCursorPos > -1) { if (mSelectionPos > -1) { float caretx = cursorIndex2Position(mCursorPos, textBound[2], glyphs, nglyphs); float selx = cursorIndex2Position(mSelectionPos, textBound[2], glyphs, nglyphs); if (caretx > selx) std::swap(caretx, selx); // draw selection nvgBeginPath(ctx); nvgFillColor(ctx, nvgRGBA(255, 255, 255, 80)); nvgRect(ctx, caretx, drawPos.y() - lineh * 0.5f, selx - caretx, lineh); nvgFill(ctx); } float caretx = cursorIndex2Position(mCursorPos, textBound[2], glyphs, nglyphs); // draw cursor nvgBeginPath(ctx); nvgMoveTo(ctx, caretx, drawPos.y() - lineh * 0.5f); nvgLineTo(ctx, caretx, drawPos.y() + lineh * 0.5f); nvgStrokeColor(ctx, nvgRGBA(255, 192, 0, 255)); nvgStrokeWidth(ctx, 1.0f); nvgStroke(ctx); } } nvgRestore(ctx); }
void Button::draw(NVGcontext * ctx) { Widget::draw(ctx); NVGcolor gradTop = mTheme->mButtonGradientTopUnfocused; NVGcolor gradBot = mTheme->mButtonGradientBotUnfocused; if (mPushed) { gradTop = mTheme->mButtonGradientTopPushed; gradBot = mTheme->mButtonGradientBotPushed; } else if (mMouseFocus && mEnabled) { gradTop = mTheme->mButtonGradientTopFocused; gradBot = mTheme->mButtonGradientBotFocused; } nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x + 1, mPos.y + 1.0f, mSize.x - 2, mSize.y - 2, mTheme->mButtonCornerRadius - 1); if (mBackgroundColor.a != 0) { nvgFillColor(ctx, Colour(mBackgroundColor.r, mBackgroundColor.g, mBackgroundColor.b, 1.f)); nvgFill(ctx); if (mPushed) gradTop.a = gradBot.a = 0.8f; else { double v = 1 - mBackgroundColor.a; gradTop.a = gradBot.a = mEnabled ? v : v * .5f + .5f; } } NVGpaint bg = nvgLinearGradient(ctx, mPos.x, mPos.y, mPos.x, mPos.y + mSize.y, gradTop, gradBot); nvgFillPaint(ctx, bg); nvgFill(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x + 0.5f, mPos.y + (mPushed ? 0.5f : 1.5f), mSize.x - 1, mSize.y - 1 - (mPushed ? 0.0f : 1.0f), mTheme->mButtonCornerRadius); nvgStrokeColor(ctx, mTheme->mBorderLight); nvgStroke(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x + 0.5f, mPos.y + 0.5f, mSize.x - 1, mSize.y - 2, mTheme->mButtonCornerRadius); nvgStrokeColor(ctx, mTheme->mBorderDark); nvgStroke(ctx); int fontSize = mFontSize == -1 ? mTheme->mButtonFontSize : mFontSize; nvgFontSize(ctx, fontSize); nvgFontFace(ctx, "sans-bold"); float tw = nvgTextBounds(ctx, 0, 0, mCaption.c_str(), nullptr, nullptr); vec2 center = vec2((float)mPos.x, (float)mPos.y) + vec2((float)mSize.x, (float)mSize.y) * 0.5f; vec2 textPos(center.x - tw * 0.5f, center.y - 1); NVGcolor textColor = mTextColor.a == 0 ? mTheme->mTextColor : mTextColor; if (!mEnabled) textColor = mTheme->mDisabledTextColor; if (mIcon) { auto icon = utf8(mIcon); float iw, ih = fontSize; if (nvgIsFontIcon(mIcon)) { ih *= 1.5f; nvgFontSize(ctx, ih); nvgFontFace(ctx, "icons"); iw = nvgTextBounds(ctx, 0, 0, icon.data(), nullptr, nullptr); } else { int w, h; ih *= 0.9f; nvgImageSize(ctx, mIcon, &w, &h); iw = w * ih / h; } if (mCaption != "") iw += mSize.y * 0.15f; nvgFillColor(ctx, textColor); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); vec2 iconPos = center; iconPos.y -= 1; if (mIconPosition == IconPosition::LeftCentered) { iconPos.x -= (tw + iw) * 0.5f; textPos.x += iw * 0.5f; } else if (mIconPosition == IconPosition::RightCentered) { textPos.x -= iw * 0.5f; iconPos.x += tw * 0.5f; } else if (mIconPosition == IconPosition::Left) iconPos.x = mPos.x + 8; else if (mIconPosition == IconPosition::Right) iconPos.x = mPos.x + mSize.x - iw - 8; if (nvgIsFontIcon(mIcon)) nvgText(ctx, iconPos.x, iconPos.y + 1, icon.data(), nullptr); else { NVGpaint imgPaint = nvgImagePattern(ctx, iconPos.x, iconPos.y - ih / 2, iw, ih, 0, mIcon, mEnabled ? 0.5f : 0.25f); nvgFillPaint(ctx, imgPaint); nvgFill(ctx); } } nvgFontSize(ctx, fontSize); nvgFontFace(ctx, "sans-bold"); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); nvgFillColor(ctx, mTheme->mTextColorShadow); nvgText(ctx, textPos.x, textPos.y, mCaption.c_str(), nullptr); nvgFillColor(ctx, textColor); nvgText(ctx, textPos.x, textPos.y + 1, mCaption.c_str(), nullptr); }
void ColorWheel::draw(NVGcontext *ctx) { Widget::draw(ctx); if (!mVisible) return; float x = mPos.x(), y = mPos.y(), w = mSize.x(), h = mSize.y(); NVGcontext* vg = ctx; int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = mHue; NVGpaint paint; nvgSave(vg); cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 * .75f; aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). for (i = 0; i < 6; i++) { float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; 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, nvgHSLA(a0 / (NVG_PI * 2), 1.0f, 0.55f, 255), nvgHSLA(a1 / (NVG_PI * 2), 1.0f, 0.55f, 255)); nvgFillPaint(vg, paint); nvgFill(vg); } nvgBeginPath(vg); nvgCircle(vg, cx,cy, r0-0.5f); nvgCircle(vg, cx,cy, r1+0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); nvgStrokeWidth(vg, 1.0f); nvgStroke(vg); // Selector nvgSave(vg); nvgTranslate(vg, cx,cy); nvgRotate(vg, hue*NVG_PI*2); // Marker on float u = std::max(r1/50, 1.5f); u = std::min(u, 4.f); nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgRect(vg, r0-1,-2*u,r1-r0+2,4*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); nvgBeginPath(vg); nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); nvgRect(vg, r0-2,-4,r1-r0+4,8); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); // Center triangle r = r0 - 6; ax = cosf(120.0f/180.0f*NVG_PI) * r; ay = sinf(120.0f/180.0f*NVG_PI) * r; bx = cosf(-120.0f/180.0f*NVG_PI) * r; by = sinf(-120.0f/180.0f*NVG_PI) * r; nvgBeginPath(vg); nvgMoveTo(vg, r,0); nvgLineTo(vg, ax, ay); nvgLineTo(vg, bx, by); nvgClosePath(vg); paint = nvgLinearGradient(vg, r, 0, ax, ay, nvgHSLA(hue, 1.0f, 0.5f, 255), nvgRGBA(255, 255, 255, 255)); nvgFillPaint(vg, paint); nvgFill(vg); paint = nvgLinearGradient(vg, (r + ax) * 0.5f, (0 + ay) * 0.5f, bx, by, nvgRGBA(0, 0, 0, 0), nvgRGBA(0, 0, 0, 255)); nvgFillPaint(vg, paint); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 64)); nvgStroke(vg); // Select circle on triangle float sx = r*(1 - mWhite - mBlack) + ax*mWhite + bx*mBlack; float sy = ay*mWhite + by*mBlack; nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgCircle(vg, sx,sy,2*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); nvgRestore(vg); nvgRestore(vg); }
JNIEXPORT void JNICALL Java_firststep_internal_NVG_stroke (JNIEnv *e, jclass c, jlong ctx) { nvgStroke((NVGcontext*)ctx); }
static void draw(NVGcontext *nvg, struct zr_command_queue *queue, int width, int height) { const struct zr_command *cmd; glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); glEnable(GL_TEXTURE_2D); nvgBeginFrame(nvg, width, height, ((float)width/(float)height)); zr_foreach_command(cmd, queue) { switch (cmd->type) { case ZR_COMMAND_NOP: break; case ZR_COMMAND_SCISSOR: { const struct zr_command_scissor *s = zr_command(scissor, cmd); nvgScissor(nvg, s->x, s->y, s->w, s->h); } break; case ZR_COMMAND_LINE: { const struct zr_command_line *l = zr_command(line, cmd); nvgBeginPath(nvg); nvgMoveTo(nvg, l->begin.x, l->begin.y); nvgLineTo(nvg, l->end.x, l->end.y); nvgFillColor(nvg, nvgRGBA(l->color.r, l->color.g, l->color.b, l->color.a)); nvgFill(nvg); } break; case ZR_COMMAND_CURVE: { const struct zr_command_curve *q = zr_command(curve, cmd); nvgBeginPath(nvg); nvgMoveTo(nvg, q->begin.x, q->begin.y); nvgBezierTo(nvg, q->ctrl[0].x, q->ctrl[0].y, q->ctrl[1].x, q->ctrl[1].y, q->end.x, q->end.y); nvgStrokeColor(nvg, nvgRGBA(q->color.r, q->color.g, q->color.b, q->color.a)); nvgStrokeWidth(nvg, 3); nvgStroke(nvg); } break; case ZR_COMMAND_RECT: { const struct zr_command_rect *r = zr_command(rect, cmd); nvgBeginPath(nvg); nvgRoundedRect(nvg, r->x, r->y, r->w, r->h, r->rounding); nvgFillColor(nvg, nvgRGBA(r->color.r, r->color.g, r->color.b, r->color.a)); nvgFill(nvg); } break; case ZR_COMMAND_CIRCLE: { const struct zr_command_circle *c = zr_command(circle, cmd); nvgBeginPath(nvg); nvgCircle(nvg, c->x + (c->w/2.0f), c->y + c->w/2.0f, c->w/2.0f); nvgFillColor(nvg, nvgRGBA(c->color.r, c->color.g, c->color.b, c->color.a)); nvgFill(nvg); } break; case ZR_COMMAND_TRIANGLE: { const struct zr_command_triangle *t = zr_command(triangle, cmd); nvgBeginPath(nvg); nvgMoveTo(nvg, t->a.x, t->a.y); nvgLineTo(nvg, t->b.x, t->b.y); nvgLineTo(nvg, t->c.x, t->c.y); nvgLineTo(nvg, t->a.x, t->a.y); nvgFillColor(nvg, nvgRGBA(t->color.r, t->color.g, t->color.b, t->color.a)); nvgFill(nvg); } break; case ZR_COMMAND_TEXT: { const struct zr_command_text *t = zr_command(text, cmd); nvgBeginPath(nvg); nvgRoundedRect(nvg, t->x, t->y, t->w, t->h, 0); nvgFillColor(nvg, nvgRGBA(t->background.r, t->background.g, t->background.b, t->background.a)); nvgFill(nvg); nvgBeginPath(nvg); nvgFillColor(nvg, nvgRGBA(t->foreground.r, t->foreground.g, t->foreground.b, t->foreground.a)); nvgFontSize(nvg, (float)t->height); nvgTextAlign(nvg, NVG_ALIGN_MIDDLE); nvgText(nvg, t->x, t->y + t->h * 0.5f, t->string, &t->string[t->length]); nvgFill(nvg); } break; case ZR_COMMAND_IMAGE: { int w, h; NVGpaint imgpaint; const struct zr_command_image *i = zr_command(image, cmd); nvgImageSize(nvg, i->img.handle.id, &w, &h); nvgBeginPath(nvg); nvgRect(nvg, i->x, i->y, i->w, i->h); nvgFillPaint(nvg, nvgImagePattern(nvg, i->x, i->y, i->w, i->h, 0, i->img.handle.id, 1)); nvgFill(nvg); } break; case ZR_COMMAND_ARC: default: break; } } zr_command_queue_clear(queue); nvgResetScissor(nvg); nvgEndFrame(nvg); glPopAttrib(); }
void NVGRenderer::stroke() { nvgStroke(m_context); }
void Window::draw(NVGcontext *ctx) { int ds = mTheme->mWindowDropShadowSize, cr = mTheme->mWindowCornerRadius; int hh = mTheme->mWindowHeaderHeight; /* Draw window */ nvgSave(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr); nvgFillColor(ctx, mMouseFocus ? mTheme->mWindowFillFocused : mTheme->mWindowFillUnfocused); nvgFill(ctx); /* Draw a drop shadow */ NVGpaint shadowPaint = nvgBoxGradient( ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr*2, ds*2, mTheme->mDropShadow, mTheme->mTransparent); nvgBeginPath(ctx); nvgRect(ctx, mPos.x()-ds,mPos.y()-ds, mSize.x()+2*ds, mSize.y()+2*ds); nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr); nvgPathWinding(ctx, NVG_HOLE); nvgFillPaint(ctx, shadowPaint); nvgFill(ctx); if (!mTitle.empty()) { /* Draw header */ NVGpaint headerPaint = nvgLinearGradient( ctx, mPos.x(), mPos.y(), mPos.x(), mPos.y() + hh, mTheme->mWindowHeaderGradientTop, mTheme->mWindowHeaderGradientBot); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), hh, cr); nvgFillPaint(ctx, headerPaint); nvgFill(ctx); nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), hh, cr); nvgStrokeColor(ctx, mTheme->mWindowHeaderSepTop); nvgSave(ctx); nvgIntersectScissor(ctx, mPos.x(), mPos.y(), mSize.x(), 0.5f); nvgStroke(ctx); nvgResetScissor(ctx); nvgRestore(ctx); nvgBeginPath(ctx); nvgMoveTo(ctx, mPos.x() + 0.5f, mPos.y() + hh - 1.5f); nvgLineTo(ctx, mPos.x() + mSize.x() - 0.5f, mPos.y() + hh - 1.5); nvgStrokeColor(ctx, mTheme->mWindowHeaderSepBot); nvgStroke(ctx); nvgFontSize(ctx, 18.0f); nvgFontFace(ctx, "sans-bold"); nvgTextAlign(ctx, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); nvgFontBlur(ctx, 2); nvgFillColor(ctx, mTheme->mDropShadow); nvgText(ctx, mPos.x() + mSize.x() / 2, mPos.y() + hh / 2, mTitle.c_str(), nullptr); nvgFontBlur(ctx, 0); nvgFillColor(ctx, mFocused ? mTheme->mWindowTitleFocused : mTheme->mWindowTitleUnfocused); nvgText(ctx, mPos.x() + mSize.x() / 2, mPos.y() + hh / 2 - 1, mTitle.c_str(), nullptr); } nvgRestore(ctx); Widget::draw(ctx); }
void Slider::draw(NVGcontext* ctx) { Vector2f center = mPos.cast<float>() + mSize.cast<float>() * 0.5f; float kr = (int) (mSize.y() * 0.4f), kshadow = 3; float startX = kr + kshadow + mPos.x(); float widthX = mSize.x() - 2*(kr+kshadow); Vector2f knobPos(startX + (mValue - mRange.first) / (mRange.second - mRange.first) * widthX, center.y() + 0.5f); NVGpaint bg = nvgBoxGradient( ctx, startX, center.y() - 3 + 1, widthX, 6, 3, 3, Color(0, mEnabled ? 32 : 10), Color(0, mEnabled ? 128 : 210)); nvgBeginPath(ctx); nvgRoundedRect(ctx, startX, center.y() - 3 + 1, widthX, 6, 2); nvgFillPaint(ctx, bg); nvgFill(ctx); if (mHighlightedRange.second != mHighlightedRange.first) { nvgBeginPath(ctx); nvgRoundedRect(ctx, startX + mHighlightedRange.first * mSize.x(), center.y() - kshadow + 1, widthX * (mHighlightedRange.second - mHighlightedRange.first), kshadow * 2, 2); nvgFillColor(ctx, mHighlightColor); nvgFill(ctx); } NVGpaint knobShadow = nvgRadialGradient(ctx, knobPos.x(), knobPos.y(), kr - kshadow, kr + kshadow, Color(0, 64), mTheme->mTransparent); nvgBeginPath(ctx); nvgRect(ctx, knobPos.x() - kr - 5, knobPos.y() - kr - 5, kr * 2 + 10, kr * 2 + 10 + kshadow); nvgCircle(ctx, knobPos.x(), knobPos.y(), kr); nvgPathWinding(ctx, NVG_HOLE); nvgFillPaint(ctx, knobShadow); nvgFill(ctx); NVGpaint knob = nvgLinearGradient(ctx, mPos.x(), center.y() - kr, mPos.x(), center.y() + kr, mTheme->mBorderLight, mTheme->mBorderMedium); NVGpaint knobReverse = nvgLinearGradient(ctx, mPos.x(), center.y() - kr, mPos.x(), center.y() + kr, mTheme->mBorderMedium, mTheme->mBorderLight); nvgBeginPath(ctx); nvgCircle(ctx, knobPos.x(), knobPos.y(), kr); nvgStrokeColor(ctx, mTheme->mBorderDark); nvgFillPaint(ctx, knob); nvgStroke(ctx); nvgFill(ctx); nvgBeginPath(ctx); nvgCircle(ctx, knobPos.x(), knobPos.y(), kr/2); nvgFillColor(ctx, Color(150, mEnabled ? 255 : 100)); nvgStrokePaint(ctx, knobReverse); nvgStroke(ctx); nvgFill(ctx); }
void VectorRenderer::renderStroke() { nvgStroke(nvg); }
void NanoInk::redrawImage() { InkStyle& skin = this->skin(); float left = mFrame.cleft(); float top = mFrame.ctop(); float width = mFrame.cwidth(); float height = mFrame.cheight(); float pleft = mFrame.pleft(); float ptop = mFrame.ptop(); float pwidth = mFrame.pwidth(); float pheight = mFrame.pheight(); float halfb = skin.borderWidth().x0() * 0.5; float b = skin.borderWidth().x0(); if(width - b <= 0.f || height - b <= 0.f) return; nvgResetDisplayList(mImageCache); nvgBindDisplayList(mCtx, mImageCache); float contentWidth = contentSize(DIM_X) - skin.padding()[DIM_X] - skin.padding()[DIM_X + 2]; float contentHeight = contentSize(DIM_Y) - skin.padding()[DIM_Y] - skin.padding()[DIM_Y + 2]; float cleft = pleft; NVGalign halign = NVG_ALIGN_LEFT; if(skin.align()[DIM_X] == CENTER) { halign = NVG_ALIGN_CENTER; cleft = pleft + pwidth / 2.f - contentWidth / 2.f; } else if(skin.align()[DIM_X] == RIGHT) { halign = NVG_ALIGN_RIGHT; cleft = pleft + pwidth - contentWidth; } float ctop = ptop; if(skin.align()[DIM_Y] == CENTER) ctop = ptop + pheight / 2.f - contentHeight / 2.f; else if(skin.align()[DIM_Y] == RIGHT) ctop = ptop + pheight - contentHeight; float c0 = mCorners.x0(); float c1 = mCorners.y0(); float c2 = mCorners.x1(); float c3 = mCorners.y1(); // Shadow if(!skin.shadow().d_null) { const Shadow& shadow = skin.shadow(); NVGpaint shadowPaint = nvgBoxGradient(mCtx, left + shadow.d_xpos - shadow.d_spread, top + shadow.d_ypos - shadow.d_spread, width + shadow.d_spread * 2.f, height + shadow.d_spread * 2.f, c0 + shadow.d_spread, shadow.d_blur, nvgRGBA(0, 0, 0, 128), nvgRGBA(0, 0, 0, 0)); nvgBeginPath(mCtx); nvgRect(mCtx, left + shadow.d_xpos - shadow.d_radius, top + shadow.d_ypos - shadow.d_radius, width + shadow.d_radius * 2.f, height + shadow.d_radius * 2.f); if(mCorners.null()) nvgRect(mCtx, left, top, width, height); else nvgRoundedBox(mCtx, left, top, width, height, c0, c1, c2, c3); nvgPathWinding(mCtx, NVG_HOLE); nvgFillPaint(mCtx, shadowPaint); nvgFill(mCtx); } // Rect nvgBeginPath(mCtx); if(mCorners.null()) nvgRect(mCtx, left + halfb, top + halfb, width - b, height - b); else nvgRoundedBox(mCtx, left + halfb, top + halfb, width - b, height - b, c0, c1, c2, c3, mFitCorners); if(skin.backgroundColour().a() > 0.f) { if(skin.topdownGradient().null()) { nvgFillColor(mCtx, nvgColour(skin.mBackgroundColour)); } else { NVGcolor first = nvgOffsetColour(skin.backgroundColour(), skin.topdownGradient().x()); NVGcolor second = nvgOffsetColour(skin.backgroundColour(), skin.topdownGradient().y()); nvgFillPaint(mCtx, (height > width) ? nvgLinearGradient(mCtx, left, top, left + width, top, first, second) : nvgLinearGradient(mCtx, left, top, left, top + height, first, second)); } nvgFill(mCtx); } if(skin.borderWidth().x0() > 0.f) { nvgStrokeWidth(mCtx, skin.borderWidth().x0()); nvgStrokeColor(mCtx, nvgColour(skin.borderColour())); nvgStroke(mCtx); } // ImageSkin if(!skin.imageSkin().null()) { const ImageSkin& imgskin = skin.mImageSkin; float margin = skin.imageSkin().d_margin * 2.f; if(imgskin.d_stretch == DIM_X) imgskin.stretchCoords(width + margin, imgskin.d_height, [this, left, ctop](ImageSkin::Section s, int x, int y, int w, int h){ this->drawSkinImage(s, float(left + x), float(ctop + y), float(w), float(h)); }); else if(imgskin.d_stretch == DIM_Y) imgskin.stretchCoords(imgskin.d_width, height + margin, [this, cleft, top](ImageSkin::Section s, int x, int y, int w, int h){ this->drawSkinImage(s, float(cleft + x), float(top + y), float(w), float(h)); }); else imgskin.stretchCoords(width + margin, height + margin, [this, left, top](ImageSkin::Section s, int x, int y, int w, int h){ this->drawSkinImage(s, float(left + x), float(top + y), float(w), float(h)); }); } if(mFrame.dclip(DIM_X) || mFrame.dclip(DIM_Y)) nvgScissor(mCtx, left, top, width, height); // Image if(mImage) this->drawImage(*mImage, cleft, ctop, contentWidth, contentHeight); if(mOverlay) this->drawImage(*mOverlay, cleft, ctop, contentWidth, contentHeight); if(mTile) this->drawImage(*mTile, left, top, width, height); if(mFrame.dclip(DIM_X) || mFrame.dclip(DIM_Y)) nvgResetScissor(mCtx); nvgBindDisplayList(mCtx, nullptr); }