void VScrollPanel::draw (NVGcontext * ctx) { if (mChildren.empty()) return; Widget * child = mChildren[0]; mChildPreferredHeight = child->preferredSize (ctx).y(); float scrollh = height() * std::min (1.0f, height() / (float) mChildPreferredHeight); nvgSave (ctx); nvgTranslate (ctx, mPos.x(), mPos.y()); nvgScissor (ctx, 0, 0, mSize.x(), mSize.y()); nvgTranslate (ctx, 0, -mScroll * (mChildPreferredHeight - mSize.y())); if (child->visible()) child->draw (ctx); nvgRestore (ctx); NVGpaint paint = nvgBoxGradient ( ctx, mPos.x() + mSize.x() - 12 + 1, mPos.y() + 4 + 1, 8, mSize.y() - 8, 3, 4, Color (0, 32), Color (0, 92)); nvgBeginPath (ctx); nvgRoundedRect (ctx, mPos.x() + mSize.x() - 12, mPos.y() + 4, 8, mSize.y() - 8, 3); nvgFillPaint (ctx, paint); nvgFill (ctx); paint = nvgBoxGradient ( ctx, mPos.x() + mSize.x() - 12 - 1, mPos.y() + 4 + (mSize.y() - 8 - scrollh) * mScroll - 1, 8, scrollh, 3, 4, Color (220, 100), Color (128, 100)); nvgBeginPath (ctx); nvgRoundedRect (ctx, mPos.x() + mSize.x() - 12 + 1, mPos.x() + 4 + 1 + (mSize.y() - 8 - scrollh) * mScroll, 8 - 2, scrollh - 2, 2); nvgFillPaint (ctx, paint); nvgFill (ctx); }
void draw_world_scale() { #ifdef GRAPHICS nvgResetTransform(vg); nvgTranslate(vg, fb_width / 2, fb_height / 2); nvgScale(vg, double(fb_width) / world::width, double(fb_height) / world::height); nvgTranslate(vg, -world::width / 2, -world::height / 2); one_pixel = double(world::width) / fb_width; #endif }
void NanoInk::drawCache(NVGdisplayList* cache) { nvgSave(mCtx); nvgTranslate(mCtx, floor(mFrame.dabsolute(DIM_X)), floor(mFrame.dabsolute(DIM_Y))); nvgDrawDisplayList(mCtx, cache); nvgRestore(mCtx); }
void Renderer2D::drawCircle( const attributes_2d& attributes, const float32_t& radius, const float32_t& border, const color_argb& color, const color_argb& borderColor, const Image2D& image, const float32_t& image_alpha, const float32_t& image_pos_x, const float32_t& image_pos_y, const float32_t& image_width, const float32_t& image_height, const float32_t& image_rotation ) { Context2D* context = _context2D; nvgSave( context ); nvgBeginPath( context ); nvgTranslate( context, attributes.position[0], attributes.position[1]); nvgSave( context ); nvgRotate( context, attributes.rotation ); nvgCircle( context, 0, 0, radius * attributes.scale ); if( image != 0 ) { NVGpaint paint = nvgImagePattern( context, image_pos_x-image_width/2, image_pos_y - image_height/2, image_width, image_height, image_rotation, image, image_alpha ); nvgFillPaint( context, paint); } else { nvgFillColor( context, nvgRGBA( color.r, color.g, color.b, color.a) ); } nvgFill(context); nvgStrokeColor( context, nvgRGBA( borderColor.r, borderColor.g, borderColor.b, borderColor.a) ); nvgStrokeWidth( context, border ); nvgStroke( context ); nvgRestore( context ); nvgRestore( context ); }
void Renderer2D::drawRectangle( const attributes_2d& attributes, const float32_t& width, const float32_t& height, const float32_t& border, const color_argb& color, const color_argb& borderColor, const Image2D& image, const float32_t& image_alpha, const float32_t& image_pos_x, const float32_t& image_pos_y, const float32_t& image_width, const float32_t& image_height, const float32_t& image_rotation ) { Context2D* context = _context2D; const float32_t sWidth = width * attributes.scale; const float32_t sHeight = height * attributes.scale; nvgSave( context ); nvgBeginPath( context ); nvgTranslate( context, attributes.position[0], attributes.position[1] ); nvgSave( context ); nvgRotate( context, attributes.rotation ); nvgRect( context, -sWidth/2, -sHeight/2, sWidth, sHeight ); if( image != 0 ) { NVGpaint paint = nvgImagePattern( context, (-sWidth/2)+image_pos_x, (-sHeight/2)+image_pos_y, image_width, image_height, image_rotation, image, image_alpha ); nvgFillPaint( context, paint); } else { nvgFillColor( context, nvgRGBA( color.r, color.g, color.b, color.a) ); } nvgFill( context ); nvgStrokeColor( context, nvgRGBA( borderColor.r, borderColor.g, borderColor.b, borderColor.a) ); nvgStrokeWidth( context, border ); nvgStroke( context ); nvgRestore( context ); nvgRestore( context ); }
void Widget::draw(NVGcontext *ctx) { #if NANOGUI_SHOW_WIDGET_BOUNDS nvgStrokeWidth(ctx, 1.0f); nvgBeginPath(ctx); nvgRect(ctx, mPos.x() - 0.5f, mPos.y() - 0.5f, mSize.x() + 1, mSize.y() + 1); nvgStrokeColor(ctx, nvgRGBA(255, 0, 0, 255)); nvgStroke(ctx); #endif if (mChildren.empty()) return; nvgTranslate(ctx, mPos.x(), mPos.y()); for (auto child : mChildren) if (child->visible()) child->draw(ctx); nvgTranslate(ctx, -mPos.x(), -mPos.y()); }
void VScrollPanel::draw(NVGcontext *ctx) { if (m_children.empty()) return; Widget *child = m_children[0]; child->set_position(Vector2i(0, -m_scroll*(m_child_preferred_height - m_size.y()))); m_child_preferred_height = child->preferred_size(ctx).y(); float scrollh = height() * std::min(1.0f, height() / (float) m_child_preferred_height); if (m_update_layout) { m_update_layout = false; child->perform_layout(ctx); } nvgSave(ctx); nvgTranslate(ctx, m_pos.x(), m_pos.y()); nvgIntersectScissor(ctx, 0, 0, m_size.x(), m_size.y()); if (child->visible()) child->draw(ctx); nvgRestore(ctx); if (m_child_preferred_height <= m_size.y()) return; NVGpaint paint = nvgBoxGradient( ctx, m_pos.x() + m_size.x() - 12 + 1, m_pos.y() + 4 + 1, 8, m_size.y() - 8, 3, 4, Color(0, 32), Color(0, 92)); nvgBeginPath(ctx); nvgRoundedRect(ctx, m_pos.x() + m_size.x() - 12, m_pos.y() + 4, 8, m_size.y() - 8, 3); nvgFillPaint(ctx, paint); nvgFill(ctx); paint = nvgBoxGradient( ctx, m_pos.x() + m_size.x() - 12 - 1, m_pos.y() + 4 + (m_size.y() - 8 - scrollh) * m_scroll - 1, 8, scrollh, 3, 4, Color(220, 100), Color(128, 100)); nvgBeginPath(ctx); nvgRoundedRect(ctx, m_pos.x() + m_size.x() - 12 + 1, m_pos.y() + 4 + 1 + (m_size.y() - 8 - scrollh) * m_scroll, 8 - 2, scrollh - 2, 2); nvgFillPaint(ctx, paint); nvgFill(ctx); }
void Renderer2D::drawPath( const attributes_2d& attributes, const float32_t* path, const uint32_t& pathSize, const float32_t& border, const color_argb& color, const color_argb& borderColor, const Image2D& image, const float32_t& image_alpha, const float32_t& image_pos_x, const float32_t& image_pos_y, const float32_t& image_width, const float32_t& image_height, const float32_t& image_rotation ) { Context2D* context = _context2D; if( pathSize < 2 || pathSize % 2 != 0 ) return; nvgSave( context ); nvgBeginPath( context ); nvgTranslate( context, attributes.position[0], attributes.position[1] ); nvgSave( context ); nvgRotate( context, attributes.rotation ); nvgMoveTo( context, path[0], path[1]); for( uint32_t i=2; i<pathSize; i+=2 ) { nvgLineTo( context, path[i] * attributes.scale, path[i+1] * attributes.scale); } nvgClosePath( context ); if( image != 0 ) { NVGpaint paint = nvgImagePattern( context, image_pos_x-image_width/2, image_pos_y-image_height/2, image_width, image_height, image_rotation, image, image_alpha ); nvgFillPaint( context, paint); } else { nvgFillColor( context, nvgRGBA( color.r, color.g, color.b, color.a) ); } nvgFill(context); nvgStrokeColor( context, nvgRGBA( borderColor.r, borderColor.g, borderColor.b, borderColor.a) ); nvgStrokeWidth( context, border ); nvgStroke( context ); nvgRestore( context ); nvgRestore( context ); }
void Cursor::draw(AlloyContext* context) const { pixel2 cursor = context->cursorPosition; if (fontSize > 0.0f && context->hasFocus && cursor.x >= 0 && cursor.y >= 0 && cursor.x < context->getScreenWidth() && cursor.y < context->getScreenHeight()) { NVGcontext* nvg = context->nvgContext; nvgTextAlign(nvg, align); nvgSave(nvg); nvgFontFaceId(nvg, context->getFontHandle(fontType)); nvgFontSize(nvg, fontSize); nvgFillColor(nvg, Color(255, 255, 255)); nvgTranslate(nvg, cursor.x+nudge.x, cursor.y+nudge.y); nvgRotate(nvg, angle); const float shift = 1.0f; const char* txt = codeString.c_str(); nvgFillColor(nvg, Color(0, 0, 0)); nvgText(nvg, +shift, 0, txt, nullptr); nvgText(nvg, -shift, 0, txt, nullptr); nvgText(nvg, 0, +shift, txt, nullptr); nvgText(nvg, 0, -shift, txt, nullptr); nvgFillColor(nvg, Color(255, 255, 255)); nvgText(nvg, 0, 0, txt, nullptr); nvgRestore(nvg); } }
void draw_demostuff(NVGcontext *vg, int x, int y, float w, float h) { nvgSave(vg); nvgTranslate(vg, x, y); bndSplitterWidgets(vg, 0, 0, w, h); x = 10; y = 10; bndToolButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, BND_ICONID(6,3),"Default"); y += 25; bndToolButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, BND_ICONID(6,3),"Hovered"); y += 25; bndToolButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, BND_ICONID(6,3),"Active"); y += 40; bndRadioButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, -1,"Default"); y += 25; bndRadioButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, -1,"Hovered"); y += 25; bndRadioButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, -1,"Active"); y += 25; bndLabel(vg,x,y,120,BND_WIDGET_HEIGHT,-1,"Label:"); y += BND_WIDGET_HEIGHT; bndChoiceButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, -1, "Default"); y += 25; bndChoiceButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, -1, "Hovered"); y += 25; bndChoiceButton(vg,x,y,80,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, -1, "Active"); y += 25; int ry = y; int rx = x; y = 10; x += 130; bndOptionButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_DEFAULT,"Default"); y += 25; bndOptionButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_HOVER,"Hovered"); y += 25; bndOptionButton(vg,x,y,120,BND_WIDGET_HEIGHT,BND_ACTIVE,"Active"); y += 40; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_DOWN,BND_DEFAULT, "Top","100"); y += BND_WIDGET_HEIGHT-2; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_ALL,BND_DEFAULT, "Center","100"); y += BND_WIDGET_HEIGHT-2; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_TOP,BND_DEFAULT, "Bottom","100"); int mx = x-30; int my = y-12; int mw = 120; bndMenuBackground(vg,mx,my,mw,120,BND_CORNER_TOP); bndMenuLabel(vg,mx,my,mw,BND_WIDGET_HEIGHT,-1,"Menu Title"); my += BND_WIDGET_HEIGHT-2; bndMenuItem(vg,mx,my,mw,BND_WIDGET_HEIGHT,BND_DEFAULT, BND_ICONID(17,3),"Default"); my += BND_WIDGET_HEIGHT-2; bndMenuItem(vg,mx,my,mw,BND_WIDGET_HEIGHT,BND_HOVER, BND_ICONID(18,3),"Hovered"); my += BND_WIDGET_HEIGHT-2; bndMenuItem(vg,mx,my,mw,BND_WIDGET_HEIGHT,BND_ACTIVE, BND_ICONID(19,3),"Active"); y = 10; x += 130; int ox = x; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, "Default","100"); y += 25; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, "Hovered","100"); y += 25; bndNumberField(vg,x,y,120,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, "Active","100"); y += 40; bndRadioButton(vg,x,y,60,BND_WIDGET_HEIGHT,BND_CORNER_RIGHT,BND_DEFAULT, -1,"One"); x += 60-1; bndRadioButton(vg,x,y,60,BND_WIDGET_HEIGHT,BND_CORNER_ALL,BND_DEFAULT, -1,"Two"); x += 60-1; bndRadioButton(vg,x,y,60,BND_WIDGET_HEIGHT,BND_CORNER_ALL,BND_DEFAULT, -1,"Three"); x += 60-1; bndRadioButton(vg,x,y,60,BND_WIDGET_HEIGHT,BND_CORNER_LEFT,BND_ACTIVE, -1,"Butts"); x = ox; y += 40; float progress_value = fmodf(glfwGetTime()/10.0,1.0); char progress_label[32]; sprintf(progress_label, "%d%%", int(progress_value*100+0.5f)); bndSlider(vg,x,y,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, progress_value,"Default",progress_label); y += 25; bndSlider(vg,x,y,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, progress_value,"Hovered",progress_label); y += 25; bndSlider(vg,x,y,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, progress_value,"Active",progress_label); int rw = x+240-rx; float s_offset = sinf(glfwGetTime()/2.0)*0.5+0.5; float s_size = cosf(glfwGetTime()/3.11)*0.5+0.5; bndScrollBar(vg,rx,ry,rw,BND_SCROLLBAR_HEIGHT,BND_DEFAULT,s_offset,s_size); ry += 20; bndScrollBar(vg,rx,ry,rw,BND_SCROLLBAR_HEIGHT,BND_HOVER,s_offset,s_size); ry += 20; bndScrollBar(vg,rx,ry,rw,BND_SCROLLBAR_HEIGHT,BND_ACTIVE,s_offset,s_size); const char edit_text[] = "The quick brown fox"; int textlen = strlen(edit_text)+1; int t = int(glfwGetTime()*2); int idx1 = (t/textlen)%textlen; int idx2 = idx1 + (t%(textlen-idx1)); ry += 25; bndTextField(vg,rx,ry,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_DEFAULT, -1, edit_text, idx1, idx2); ry += 25; bndTextField(vg,rx,ry,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_HOVER, -1, edit_text, idx1, idx2); ry += 25; bndTextField(vg,rx,ry,240,BND_WIDGET_HEIGHT,BND_CORNER_NONE,BND_ACTIVE, -1, edit_text, idx1, idx2); draw_noodles(vg, 20, ry+50); rx += rw + 20; ry = 10; bndScrollBar(vg,rx,ry,BND_SCROLLBAR_WIDTH,240,BND_DEFAULT,s_offset,s_size); rx += 20; bndScrollBar(vg,rx,ry,BND_SCROLLBAR_WIDTH,240,BND_HOVER,s_offset,s_size); rx += 20; bndScrollBar(vg,rx,ry,BND_SCROLLBAR_WIDTH,240,BND_ACTIVE,s_offset,s_size); x = ox; y += 40; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_RIGHT, BND_DEFAULT,BND_ICONID(0,10),NULL); x += BND_TOOL_WIDTH-1; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(1,10),NULL); x += BND_TOOL_WIDTH-1; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(2,10),NULL); x += BND_TOOL_WIDTH-1; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(3,10),NULL); x += BND_TOOL_WIDTH-1; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(4,10),NULL); x += BND_TOOL_WIDTH-1; bndToolButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_LEFT, BND_DEFAULT,BND_ICONID(5,10),NULL); x += BND_TOOL_WIDTH-1; x += 5; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_RIGHT, BND_DEFAULT,BND_ICONID(0,11),NULL); x += BND_TOOL_WIDTH-1; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(1,11),NULL); x += BND_TOOL_WIDTH-1; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(2,11),NULL); x += BND_TOOL_WIDTH-1; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_DEFAULT,BND_ICONID(3,11),NULL); x += BND_TOOL_WIDTH-1; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_ALL, BND_ACTIVE,BND_ICONID(4,11),NULL); x += BND_TOOL_WIDTH-1; bndRadioButton(vg,x,y,BND_TOOL_WIDTH,BND_WIDGET_HEIGHT,BND_CORNER_LEFT, BND_DEFAULT,BND_ICONID(5,11),NULL); nvgRestore(vg); }
JNIEXPORT void JNICALL Java_org_lwjgl_nanovg_NanoVG_nnvgTranslate(JNIEnv *__env, jclass clazz, jlong ctxAddress, jfloat x, jfloat y) { NVGcontext *ctx = (NVGcontext *)(intptr_t)ctxAddress; UNUSED_PARAMS(__env, clazz) nvgTranslate(ctx, x, y); }
void GraphPane::draw(AlloyContext* context) { Region::draw(context); box2px rbounds = getBounds(); NVGcontext* nvg = context->nvgContext; box2px gbounds = rbounds; const float LARGE_TEXT = 18.0f; const float MEDIUM_TEXT = 16.0f; const float SMALL_TEXT = 12.0f; float2 gpos(-1, -1); gbounds.position = pixel2(rbounds.position.x + GRAPH_PADDING, rbounds.position.y + GRAPH_PADDING); gbounds.dimensions = pixel2(rbounds.dimensions.x - GRAPH_PADDING * 2, rbounds.dimensions.y - GRAPH_PADDING * 2); if (graphBounds.dimensions.x < 0 || graphBounds.dimensions.y < 0) { updateGraphBounds(); } nvgBeginPath(nvg); nvgRoundedRect(nvg, gbounds.position.x - 2, gbounds.position.y - 2, gbounds.dimensions.x + 4, gbounds.dimensions.y + 4, context->theme.CORNER_RADIUS); nvgFillColor(nvg, context->theme.LIGHTEST); nvgFill(nvg); //Draw vertical line for x=0 if (graphBounds.position.x < 0 && graphBounds.position.x + graphBounds.dimensions.x > 0) { float xpos = -graphBounds.position.x / graphBounds.dimensions.x; nvgBeginPath(nvg); nvgMoveTo(nvg, xpos * gbounds.dimensions.x + gbounds.position.x, gbounds.position.y); nvgLineTo(nvg, xpos * gbounds.dimensions.x + gbounds.position.x, gbounds.position.y + gbounds.dimensions.y); nvgStrokeWidth(nvg, 2.0f); nvgStrokeColor(nvg, context->theme.DARK.toSemiTransparent(0.75f)); nvgStroke(nvg); } //Draw horizontal line for y=0 if (graphBounds.position.y < 0 && graphBounds.position.y + graphBounds.dimensions.y > 0) { float ypos = -graphBounds.position.y / graphBounds.dimensions.y; nvgBeginPath(nvg); nvgMoveTo(nvg, gbounds.position.x, ypos * gbounds.dimensions.y + gbounds.position.y); nvgLineTo(nvg, gbounds.position.x + gbounds.dimensions.x, ypos * gbounds.dimensions.y + gbounds.position.y); nvgStrokeWidth(nvg, 2.0f); nvgStrokeColor(nvg, context->theme.DARK.toSemiTransparent(0.75f)); nvgStroke(nvg); } if (gbounds.contains(cursorPosition)) { context->setCursor(&Cursor::CrossHairs); gpos = (cursorPosition - gbounds.position) / gbounds.dimensions; gpos.y = 1 - gpos.y; gpos = gpos * graphBounds.dimensions + graphBounds.position; nvgBeginPath(nvg); nvgMoveTo(nvg, cursorPosition.x, gbounds.position.y); nvgLineTo(nvg, cursorPosition.x, gbounds.position.y + gbounds.dimensions.y); nvgStrokeWidth(nvg, 1.0f); nvgStrokeColor(nvg, context->theme.DARK.toSemiTransparent(0.25f)); nvgStroke(nvg); nvgBeginPath(nvg); nvgMoveTo(nvg, gbounds.position.x, cursorPosition.y); nvgLineTo(nvg, gbounds.position.x + gbounds.dimensions.x, cursorPosition.y); nvgStrokeWidth(nvg, 1.0f); nvgStrokeColor(nvg, context->theme.DARK.toSemiTransparent(0.25f)); nvgStroke(nvg); } for (GraphDataPtr& curve : curves) { std::vector<float2> points = curve->points; if (points.size() > 1 && graphBounds.dimensions.x > 0.0f && graphBounds.dimensions.y > 0.0f) { NVGcontext* nvg = context->nvgContext; float2 last = points[0]; last = (last - graphBounds.position) / graphBounds.dimensions; last.y = 1.0f - last.y; last = last * gbounds.dimensions + gbounds.position; nvgBeginPath(nvg); nvgMoveTo(nvg, last.x, last.y); for (int i = 1; i < (int)points.size(); i++) { float2 pt = points[i]; pt = (pt - graphBounds.position) / graphBounds.dimensions; pt.y = 1.0f - pt.y; pt = pt * gbounds.dimensions + gbounds.position; nvgLineTo(nvg, pt.x, pt.y); last = pt; } nvgStrokeWidth(nvg, 2.0f); nvgStrokeColor(nvg, curve->color); nvgStroke(nvg); } } nvgFontFaceId(nvg, context->getFontHandle(FontType::Bold)); nvgFontSize(nvg, LARGE_TEXT); nvgTextAlign(nvg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); drawText(nvg, rbounds.position + float2(rbounds.dimensions.x / 2, 2.0f), name, FontStyle::Outline, context->theme.LIGHTEST, context->theme.DARK); nvgFontSize(nvg, MEDIUM_TEXT); nvgFontFaceId(nvg, context->getFontHandle(FontType::Bold)); nvgTextAlign(nvg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); drawText(nvg, rbounds.position + float2(rbounds.dimensions.x / 2, rbounds.dimensions.y - 4.0f), xAxisLabel, FontStyle::Outline, context->theme.LIGHTEST, context->theme.DARK); nvgTextAlign(nvg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); nvgSave(nvg); pixel2 center = rbounds.position + float2(2.0f, rbounds.dimensions.y * 0.5f); nvgTranslate(nvg, center.x, center.y); nvgRotate(nvg, -ALY_PI * 0.5f); drawText(nvg, pixel2(0, 2), yAxisLabel, FontStyle::Outline, context->theme.LIGHTEST, context->theme.DARK); nvgRestore(nvg); nvgFontSize(nvg, SMALL_TEXT); nvgTextAlign(nvg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP); drawText(nvg, rbounds.position + float2(GRAPH_PADDING, GRAPH_PADDING), MakeString() << std::setprecision(2) << (graphBounds.position.y + graphBounds.dimensions.y), FontStyle::Outline, context->theme.LIGHTER, context->theme.DARK); nvgTextAlign(nvg, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM); drawText(nvg, rbounds.position + float2(GRAPH_PADDING, rbounds.dimensions.y - GRAPH_PADDING), MakeString() << std::setprecision(2) << graphBounds.position.y, FontStyle::Outline, context->theme.LIGHTER, context->theme.DARK); nvgTextAlign(nvg, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP); drawText(nvg, rbounds.position + float2(rbounds.dimensions.x - GRAPH_PADDING, rbounds.dimensions.y - GRAPH_PADDING + 2), MakeString() << std::setprecision(2) << (graphBounds.position.x + graphBounds.dimensions.x), FontStyle::Outline, context->theme.LIGHTER, context->theme.DARK); nvgTextAlign(nvg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); drawText(nvg, rbounds.position + float2(GRAPH_PADDING, rbounds.dimensions.y - GRAPH_PADDING + 2), MakeString() << std::setprecision(2) << graphBounds.position.x, FontStyle::Outline, context->theme.LIGHTER, context->theme.DARK); if (cursorPosition.x >= 0) { float minDist = 1E30f; float bestY = 0; GraphDataPtr closestCurve; for (GraphDataPtr& curve : curves) { float y = curve->interpolate(gpos.x); if (y != GraphData::NO_INTERSECT) { if (std::abs(y - gpos.y) < minDist) { minDist = std::abs(y - gpos.y); bestY = y; closestCurve = curve; } } } if (closestCurve.get() != nullptr) { nvgBeginPath(nvg); nvgStrokeWidth(nvg, 2.0f); nvgFillColor(nvg, closestCurve->color); nvgStrokeColor(nvg, context->theme.LIGHTER); float2 pt(gpos.x, bestY); pt = (pt - graphBounds.position) / graphBounds.dimensions; pt.y = 1.0f - pt.y; pt = pt * gbounds.dimensions + gbounds.position; nvgCircle(nvg, pt.x, pt.y, 4); nvgFill(nvg); nvgStroke(nvg); nvgBeginPath(nvg); nvgFillColor(nvg, context->theme.DARK); nvgCircle(nvg, cursorPosition.x, cursorPosition.y, 2); nvgFill(nvg); nvgTextAlign(nvg, NVG_ALIGN_RIGHT | NVG_ALIGN_MIDDLE); nvgFontSize(nvg, MEDIUM_TEXT); drawText(nvg, float2(pt.x - 8, pt.y), closestCurve->name, FontStyle::Outline, context->theme.LIGHTEST, context->theme.DARK); nvgTextAlign(nvg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); drawText(nvg, float2(pt.x + 8, pt.y), MakeString() << "(" << std::setprecision(2) << gpos.x << ", " << std::setprecision(2) << bestY << ")", FontStyle::Outline, context->theme.LIGHTEST, context->theme.DARK); } else { nvgBeginPath(nvg); nvgFillColor(nvg, context->theme.DARK); nvgCircle(nvg, cursorPosition.x, cursorPosition.y, 2); nvgFill(nvg); } } }
void NVGRenderer::translate(float x, float y) { nvgTranslate(m_context, x, y); }
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); }
void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, float t) { int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = sinf(t * 0.12f); struct NVGpaint paint; nvgSave(vg); /* nvgBeginPath(vg); nvgRect(vg, x,y,w,h); nvgFillColor(vg, nvgRGBA(255,0,0,128) ); nvgFill(vg);*/ cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 - 20.0f; 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 nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgRect(vg, r0-1,-3,r1-r0+2,6); 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 ax = cosf(120.0f/180.0f*NVG_PI) * r*0.3f; ay = sinf(120.0f/180.0f*NVG_PI) * r*0.4f; nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgCircle(vg, ax,ay,5); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); paint = nvgRadialGradient(vg, ax,ay, 7,9, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, ax-20,ay-20,40,40); nvgCircle(vg, ax,ay,7); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); nvgRestore(vg); nvgRestore(vg); }
void QNanoPainter::translate(float x, float y) { nvgTranslate(nvgCtx(), x, y); }
JNIEXPORT void JNICALL Java_firststep_internal_NVG_translate (JNIEnv *e, jclass c, jlong ctx, jfloat x, jfloat y) { nvgTranslate((NVGcontext*)ctx, x, y); }
void Screen::drawWidgets() { if (!mVisible) return; Vector2i oldFBSize(mFBSize); glfwMakeContextCurrent(mGLFWWindow); glfwGetFramebufferSize(mGLFWWindow, &mFBSize[0], &mFBSize[1]); glfwGetWindowSize(mGLFWWindow, &mSize[0], &mSize[1]); glViewport(0, 0, mFBSize[0], mFBSize[1]); if (oldFBSize != mFBSize) framebufferSizeChanged(); /* Calculate pixel ratio for hi-dpi devices. */ mPixelRatio = (float) mFBSize[0] / (float) mSize[0]; nvgBeginFrame(mNVGContext, mSize[0], mSize[1], mPixelRatio); nvgTranslate(mNVGContext, -2, -2); draw(mNVGContext); double elapsed = glfwGetTime() - mLastInteraction; if (elapsed > 0.5f) { /* Draw tooltips */ const Widget *widget = findWidget(mMousePos); if (widget && !widget->tooltip().empty()) { int tooltipWidth = 150; float bounds[4]; nvgFontFace(mNVGContext, "sans"); nvgFontSize(mNVGContext, 15.0f); nvgTextAlign(mNVGContext, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); nvgTextLineHeight(mNVGContext, 1.1f); Vector2i pos = widget->absolutePosition() + Vector2i(widget->width() / 2, widget->height() + 10); nvgTextBoxBounds(mNVGContext, pos.x(), pos.y(), tooltipWidth, widget->tooltip().c_str(), nullptr, bounds); nvgGlobalAlpha(mNVGContext, std::min(1.0, 2 * (elapsed - 0.5f)) * 0.8); nvgBeginPath(mNVGContext); nvgFillColor(mNVGContext, Color(0, 255)); int h = (bounds[2] - bounds[0]) / 2; nvgRoundedRect(mNVGContext, bounds[0] - 4 - h, bounds[1] - 4, (int) (bounds[2] - bounds[0]) + 8, (int) (bounds[3] - bounds[1]) + 8, 3); int px = (int) ((bounds[2] + bounds[0]) / 2) - h; nvgMoveTo(mNVGContext, px, bounds[1] - 10); nvgLineTo(mNVGContext, px + 7, bounds[1] + 1); nvgLineTo(mNVGContext, px - 7, bounds[1] + 1); nvgFill(mNVGContext); nvgFillColor(mNVGContext, Color(255, 255)); nvgFontBlur(mNVGContext, 0.0f); nvgTextBox(mNVGContext, pos.x() - h, pos.y(), tooltipWidth, widget->tooltip().c_str(), nullptr); } } nvgEndFrame(mNVGContext); }
void NanoVG::translate( float x, float y ) { nvgTranslate( m_context(), x, y ); }
void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, const int* images, int nimages, float t) { float cornerRadius = 3.0f; struct NVGpaint shadowPaint, imgPaint, fadePaint; float ix,iy,iw,ih; float thumb = 60.0f; float arry = 30.5f; int imgw, imgh; float stackh = (nimages/2) * (thumb+10) + 10; int i; float u = (1+cosf(t*0.5f) )*0.5f; float scrollh; nvgSave(vg); // nvgClearState(vg); // Drop shadow shadowPaint = nvgBoxGradient(vg, x,y+4, w,h, cornerRadius*2, 20, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, x-10,y-10, w+20,h+30); nvgRoundedRect(vg, x,y, w,h, cornerRadius); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, shadowPaint); nvgFill(vg); // Window nvgBeginPath(vg); nvgRoundedRect(vg, x,y, w,h, cornerRadius); nvgMoveTo(vg, x-10,y+arry); nvgLineTo(vg, x+1,y+arry-11); nvgLineTo(vg, x+1,y+arry+11); nvgFillColor(vg, nvgRGBA(200,200,200,255) ); nvgFill(vg); nvgSave(vg); nvgScissor(vg, x,y,w,h); nvgTranslate(vg, 0, -(stackh - h)*u); for (i = 0; i < nimages; i++) { float tx, ty; tx = x+10; ty = y+10; tx += (i%2) * (thumb+10); ty += (i/2) * (thumb+10); nvgImageSize(vg, images[i], &imgw, &imgh); if (imgw < imgh) { iw = thumb; ih = iw * (float)imgh/(float)imgw; ix = 0; iy = -(ih-thumb)*0.5f; } else { ih = thumb; iw = ih * (float)imgw/(float)imgh; 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); nvgBeginPath(vg); nvgRoundedRect(vg, tx,ty, thumb,thumb, 5); nvgFillPaint(vg, imgPaint); nvgFill(vg); shadowPaint = nvgBoxGradient(vg, tx-1,ty, thumb+2,thumb+2, 5, 3, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, tx-5,ty-5, thumb+10,thumb+10); nvgRoundedRect(vg, tx,ty, thumb,thumb, 6); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, shadowPaint); nvgFill(vg); nvgBeginPath(vg); nvgRoundedRect(vg, tx+0.5f,ty+0.5f, thumb-1,thumb-1, 4-0.5f); nvgStrokeWidth(vg,1.0f); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); } nvgRestore(vg); // Hide fades fadePaint = nvgLinearGradient(vg, x,y,x,y+6, nvgRGBA(200,200,200,255), nvgRGBA(200,200,200,0) ); nvgBeginPath(vg); nvgRect(vg, x+4,y,w-8,6); nvgFillPaint(vg, fadePaint); nvgFill(vg); fadePaint = nvgLinearGradient(vg, x,y+h,x,y+h-6, nvgRGBA(200,200,200,255), nvgRGBA(200,200,200,0) ); nvgBeginPath(vg); nvgRect(vg, x+4,y+h-6,w-8,6); nvgFillPaint(vg, fadePaint); nvgFill(vg); // Scroll bar shadowPaint = nvgBoxGradient(vg, x+w-12+1,y+4+1, 8,h-8, 3,4, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,92) ); nvgBeginPath(vg); nvgRoundedRect(vg, x+w-12,y+4, 8,h-8, 3); nvgFillPaint(vg, shadowPaint); // nvgFillColor(vg, nvgRGBA(255,0,0,128) ); nvgFill(vg); scrollh = (h/stackh) * (h-8); shadowPaint = nvgBoxGradient(vg, x+w-12-1,y+4+(h-8-scrollh)*u-1, 8,scrollh, 3,4, nvgRGBA(220,220,220,255), nvgRGBA(128,128,128,255) ); nvgBeginPath(vg); nvgRoundedRect(vg, x+w-12+1,y+4+1 + (h-8-scrollh)*u, 8-2,scrollh-2, 2); nvgFillPaint(vg, shadowPaint); // nvgFillColor(vg, nvgRGBA(0,0,0,128) ); nvgFill(vg); nvgRestore(vg); }
void drawClock(NVGcontext* vg, int screenWidth, int screenHeight) { int clockRadius = (fmin(screenWidth, screenHeight) - 10) / 2; NVGcolor baseColor = nvgRGB(145, 100, 0); NVGcolor lighterColor = nvgRGB(200, 140, 0); NVGcolor dblLighterColor = nvgRGB(255, 177, 0); NVGcolor lightestColor = nvgRGB(255, 195, 60); int widthLight = fmax(clockRadius * 0.0075, 1); int widthMedium = fmax(clockRadius * 0.013, 1); int widthHeavy = fmax(clockRadius * 0.025, 1); time_t t = time(NULL); struct tm localTime = *localtime(&t); nvgTranslate(vg, screenWidth / 2, screenHeight / 2); nvgStrokeColor(vg, baseColor); // Frame nvgSave(vg); nvgBeginPath(vg); nvgCircle(vg, 0, 0, clockRadius); nvgStrokeWidth(vg, widthMedium); nvgStroke(vg); nvgBeginPath(vg); nvgStrokeColor(vg, lighterColor); for (int i = 0; i < 12; i++) { nvgMoveTo(vg, 0, -clockRadius * 0.98); nvgLineTo(vg, 0, -clockRadius * 0.90); for (int j = 0; j < 5; j++) { nvgRotate(vg, 2 * M_PI / 12 / 5); nvgMoveTo(vg, 0, -clockRadius * 0.98); nvgLineTo(vg, 0, -clockRadius * 0.95); } } nvgStroke(vg); nvgBeginPath(vg); nvgFontFace(vg, "bold"); int digitsRadius = clockRadius * 0.79; int digitLargeSize = clockRadius * 0.29; int digitSmallSize = clockRadius * 0.2; int clockTitleSize = clockRadius * 0.06; nvgFillColor(vg, dblLighterColor); char* nineTitle = "9"; nvgFontSize(vg, digitLargeSize); nvgTranslate(vg, -digitsRadius, 0); nvgRotate(vg, - 3 * 2 * M_PI / 12); //nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, nineTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, lighterColor); char* tenTitle = "10"; nvgFontSize(vg, digitSmallSize); nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, tenTitle, 0, 0); nvgFill(vg); char* elevenTitle = "11"; nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, elevenTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, dblLighterColor); char* twelveTitle = "12"; nvgFontSize(vg, digitLargeSize); nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, twelveTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, lighterColor); char* oneTitle = "1"; nvgFontSize(vg, digitSmallSize); nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, oneTitle, 0, 0); nvgFill(vg); char* twoTitle = "2"; nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, twoTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, dblLighterColor); char* threeTitle = "3"; nvgFontSize(vg, digitLargeSize); nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, -digitsRadius); drawTextCenter(vg, threeTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, lighterColor); char* fourTitle = "4"; nvgFontSize(vg, digitSmallSize); nvgTranslate(vg, 0, digitsRadius); nvgRotate(vg, 2 * M_PI / 12 - M_PI); nvgTranslate(vg, 0, digitsRadius); drawTextCenter(vg, fourTitle, 0, 0); nvgFill(vg); char* fiveTitle = "5"; nvgTranslate(vg, 0, -digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, digitsRadius); drawTextCenter(vg, fiveTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, dblLighterColor); char* sixTitle = "6"; nvgFontSize(vg, digitLargeSize); nvgTranslate(vg, 0, -digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, digitsRadius); drawTextCenter(vg, sixTitle, 0, 0); nvgFill(vg); nvgFillColor(vg, lighterColor); char* sevenTitle = "7"; nvgFontSize(vg, digitSmallSize); nvgTranslate(vg, 0, -digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, digitsRadius); drawTextCenter(vg, sevenTitle, 0, 0); nvgFill(vg); char* eightTitle = "8"; nvgTranslate(vg, 0, -digitsRadius); nvgRotate(vg, 2 * M_PI / 12); nvgTranslate(vg, 0, digitsRadius); drawTextCenter(vg, eightTitle, 0, 0); nvgFill(vg); nvgRestore(vg); nvgSave(vg); nvgFontFace(vg, "black"); char* clockTitle = "ALPHA"; nvgFontSize(vg, clockTitleSize); nvgFillColor(vg, baseColor); nvgTranslate(vg, 0, clockTitleSize); nvgTextLetterSpacing(vg, clockTitleSize); drawTextCenter(vg, clockTitle, 0, -2 * clockTitleSize); nvgFill(vg); nvgRestore(vg); double secAngle = 2 * M_PI / 60 * localTime.tm_sec; double minAngle = 2 * M_PI / 60 * localTime.tm_min + secAngle / 60; double hrAngle = 2 * M_PI / 12 * localTime.tm_hour + minAngle / 60; // Hour hand nvgStrokeColor(vg, lighterColor); nvgSave(vg); nvgRotate(vg, hrAngle); nvgBeginPath(vg); nvgMoveTo(vg, 0, clockRadius * 0.02); nvgLineTo(vg, 0, -clockRadius * 0.5); nvgStrokeWidth(vg, widthHeavy); nvgStroke(vg); nvgRestore(vg); // Minute hand nvgStrokeColor(vg, lighterColor); nvgSave(vg); nvgRotate(vg, minAngle); nvgBeginPath(vg); nvgMoveTo(vg, 0, clockRadius * 0.04); nvgLineTo(vg, 0, -clockRadius * 0.8); nvgStrokeWidth(vg, widthMedium); nvgStroke(vg); nvgRestore(vg); // Second hand nvgStrokeColor(vg, lightestColor); nvgSave(vg); nvgRotate(vg, secAngle); nvgBeginPath(vg); nvgMoveTo(vg, 0, clockRadius * 0.05); nvgLineTo(vg, 0, -clockRadius * 0.9); nvgStrokeWidth(vg, widthLight); nvgStroke(vg); nvgRestore(vg); }