void drawLines(struct NVGcontext* vg, float x, float y, float w, float h, float t) { int i, j; float pad = 5.0f, s = w/9.0f - pad*2; float pts[4*2], fx, fy; int joins[3] = {NVG_MITER, NVG_ROUND, NVG_BEVEL}; int caps[3] = {NVG_BUTT, NVG_ROUND, NVG_SQUARE}; NVG_NOTUSED(h); nvgSave(vg); pts[0] = -s*0.25f + cosf(t*0.3f) * s*0.5f; pts[1] = sinf(t*0.3f) * s*0.5f; pts[2] = -s*0.25f; pts[3] = 0; pts[4] = s*0.25f; pts[5] = 0; pts[6] = s*0.25f + cosf(-t*0.3f) * s*0.5f; pts[7] = sinf(-t*0.3f) * s*0.5f; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { fx = x + s*0.5f + (i*3+j)/9.0f*w + pad; fy = y - s*0.5f + pad; nvgLineCap(vg, caps[i]); nvgLineJoin(vg, joins[j]); nvgStrokeWidth(vg, s*0.3f); nvgStrokeColor(vg, nvgRGBA(0,0,0,160) ); nvgBeginPath(vg); nvgMoveTo(vg, fx+pts[0], fy+pts[1]); nvgLineTo(vg, fx+pts[2], fy+pts[3]); nvgLineTo(vg, fx+pts[4], fy+pts[5]); nvgLineTo(vg, fx+pts[6], fy+pts[7]); nvgStroke(vg); nvgLineCap(vg, NVG_BUTT); nvgLineJoin(vg, NVG_BEVEL); nvgStrokeWidth(vg, 1.0f); nvgStrokeColor(vg, nvgRGBA(0,192,255,255) ); nvgBeginPath(vg); nvgMoveTo(vg, fx+pts[0], fy+pts[1]); nvgLineTo(vg, fx+pts[2], fy+pts[3]); nvgLineTo(vg, fx+pts[4], fy+pts[5]); nvgLineTo(vg, fx+pts[6], fy+pts[7]); nvgStroke(vg); } } nvgRestore(vg); }
void Popup::draw(NVGcontext* ctx) { refreshRelativePlacement(); if (!mVisible) return; int ds = mTheme->mWindowDropShadowSize, cr = mTheme->mWindowCornerRadius; /* 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); /* Draw window */ nvgBeginPath(ctx); nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr); nvgMoveTo(ctx, mPos.x()-15,mPos.y()+mAnchorHeight); nvgLineTo(ctx, mPos.x()+1,mPos.y()+mAnchorHeight-15); nvgLineTo(ctx, mPos.x()+1,mPos.y()+mAnchorHeight+15); nvgFillColor(ctx, mTheme->mWindowPopup); nvgFill(ctx); Widget::draw(ctx); }
void vsDropShadow(NVGcontext *ctx, float x, float y, float w, float h, float r, float feather, float alpha) { nvgBeginPath(ctx); y += feather; h -= feather; nvgMoveTo(ctx, x - feather, y - feather); nvgLineTo(ctx, x, y - feather); nvgLineTo(ctx, x, y + h - feather); nvgArcTo(ctx, x, y + h, x + r, y + h, r); nvgArcTo(ctx, x + w, y + h, x + w, y + h - r, r); nvgLineTo(ctx, x + w, y - feather); nvgLineTo(ctx, x + w + feather, y - feather); nvgLineTo(ctx, x + w + feather, y + h + feather); nvgLineTo(ctx, x - feather, y + h + feather); nvgClosePath(ctx); nvgFillPaint(ctx, nvgBoxGradient(ctx, x - feather * 0.5f, y - feather * 0.5f, w + feather, h + feather, r + feather * 0.5f, feather, nvgRGBAf(0, 0, 0, alpha * alpha), nvgRGBAf(0, 0, 0, 0))); nvgFill(ctx); }
void nvguLine(NVGcontext* ctx, float x0, float y0, float x1, float y1) { nvgBeginPath(ctx); nvgMoveTo(ctx, x0, y0); nvgLineTo(ctx, x1, y1); nvgStroke(ctx); }
void drawCaps(struct NVGcontext* vg, float x, float y, float width) { int i; int caps[3] = {NVG_BUTT, NVG_ROUND, NVG_SQUARE}; float lineWidth = 8.0f; nvgSave(vg); nvgBeginPath(vg); nvgRect(vg, x-lineWidth/2, y, width+lineWidth, 40); nvgFillColor(vg, nvgRGBA(255,255,255,32)); nvgFill(vg); nvgBeginPath(vg); nvgRect(vg, x, y, width, 40); nvgFillColor(vg, nvgRGBA(255,255,255,32)); nvgFill(vg); nvgStrokeWidth(vg, lineWidth); for (i = 0; i < 3; i++) { nvgLineCap(vg, caps[i]); nvgStrokeColor(vg, nvgRGBA(0,0,0,255)); nvgBeginPath(vg); nvgMoveTo(vg, x, y + i*10 + 5); nvgLineTo(vg, x+width, y + i*10 + 5); nvgStroke(vg); } nvgRestore(vg); }
void vsColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, NVGcolor color0, NVGcolor color1) { float length = bnd_fmaxf(fabsf(x1 - x0), fabsf(y1 - y0)); // how much a noodle curves (0 to 10) int noodleCurving = 3; float delta = length * (float) noodleCurving / 10.0f; nvgBeginPath(ctx); nvgMoveTo(ctx, x0, y0); nvgBezierTo(ctx, x0 + delta, y0, x1 - delta, y1, x1, y1); NVGcolor colorw = nvgRGB(52, 22, 99); colorw.a = (color0.a < color1.a) ? color0.a : color1.a; nvgStrokeColor(ctx, colorw); nvgStrokeWidth(ctx, BND_NODE_WIRE_OUTLINE_WIDTH); nvgStroke(ctx); nvgStrokePaint(ctx, nvgLinearGradient(ctx, x0, y0, x1, y1, color0, color1)); nvgStrokeWidth(ctx, BND_NODE_WIRE_WIDTH); nvgStroke(ctx); }
void Screen::drawWidgets() { if (!mVisible) return; glfwMakeContextCurrent(mGLFWWindow); glfwGetFramebufferSize(mGLFWWindow, &mFBSize[0], &mFBSize[1]); glfwGetWindowSize(mGLFWWindow, &mSize[0], &mSize[1]); glViewport(0, 0, mFBSize[0], mFBSize[1]); /* Calculate pixel ratio for hi-dpi devices. */ mPixelRatio = (float) mFBSize[0] / (float) mSize[0]; nvgBeginFrame(mNVGContext, mSize[0], mSize[1], mPixelRatio); 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); }
static void drawLine(float x0, float y0, float x1, float y1, float r, float fth, unsigned int col) { nvgBeginPath(vg::ctx); nvgFillColor(vg::ctx, nvgRGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff)); nvgMoveTo(vg::ctx, x0, y0); nvgLineTo(vg::ctx, x1, y1); nvgFill(vg::ctx); }
static void draw_line(NVGcontext *ctx, float x0, float y0, float x1, float y1, struct gui_color c) { nvgBeginPath(ctx); nvgMoveTo(ctx, x0, y0); nvgLineTo(ctx, x1, y1); nvgFillColor(ctx, nvgRGBA(c.r, c.g, c.b, c.a)); nvgFill(ctx); }
void draw<line_t>(line_t& line, NVGcolor& color) { nvgBeginPath(graphics::vg); nvgMoveTo(graphics::vg, line.p.x, line.p.y); nvgLineTo(graphics::vg, line.q.x, line.q.y); nvgStrokeColor(graphics::vg, color); nvgStrokeWidth(graphics::vg, 3 * graphics::one_pixel); nvgStroke(graphics::vg); }
static void draw_line(NVGcontext *ctx, float x0, float y0, float x1, float y1, const gui_byte *c) { nvgBeginPath(ctx); nvgMoveTo(ctx, x0, y0); nvgLineTo(ctx, x1, y1); nvgFillColor(ctx, nvgRGBA(c[0], c[1], c[2], c[3])); nvgFill(ctx); }
void Graph::draw(NVGcontext *ctx) { Widget::draw(ctx); nvgBeginPath(ctx); nvgRect(ctx, mPos.x, mPos.y, mSize.x, mSize.y); nvgFillColor(ctx, mBackgroundColor); nvgFill(ctx); if (mValues.size() < 2) return; nvgBeginPath(ctx); nvgMoveTo(ctx, mPos.x, mPos.y + mSize.y); for (size_t i = 0; i < (size_t)mValues.size(); i++) { float value = mValues[i]; float vx = mPos.x + i * mSize.x / (float)(mValues.size() - 1); float vy = mPos.y + (1 - value) * mSize.y; nvgLineTo(ctx, vx, vy); } nvgLineTo(ctx, mPos.x + mSize.x, mPos.y + mSize.y); nvgStrokeColor(ctx, Colour(100, 255)); nvgStroke(ctx); nvgFillColor(ctx, mForegroundColor); nvgFill(ctx); nvgFontFace(ctx, "sans"); if (!mCaption.empty()) { nvgFontSize(ctx, 14.0f); nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); nvgFillColor(ctx, mTextColor); nvgText(ctx, mPos.x + 3, mPos.y + 1, mCaption.c_str(), NULL); } if (!mHeader.empty()) { nvgFontSize(ctx, 18.0f); nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP); nvgFillColor(ctx, mTextColor); nvgText(ctx, mPos.x + mSize.x - 3, mPos.y + 1, mHeader.c_str(), NULL); } if (!mFooter.empty()) { nvgFontSize(ctx, 15.0f); nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM); nvgFillColor(ctx, mTextColor); nvgText(ctx, mPos.x + mSize.x - 3, mPos.y + mSize.y - 1, mFooter.c_str(), NULL); } nvgBeginPath(ctx); nvgRect(ctx, mPos.x, mPos.y, mSize.x, mSize.y); nvgStrokeColor(ctx, Colour(100, 255)); nvgStroke(ctx); }
void drawWindow(struct NVGcontext* vg, const char* title, float x, float y, float w, float h) { float cornerRadius = 3.0f; struct NVGpaint shadowPaint; struct NVGpaint headerPaint; nvgSave(vg); // nvgClearState(vg); // Window nvgBeginPath(vg); nvgRoundedRect(vg, x,y, w,h, cornerRadius); nvgFillColor(vg, nvgRGBA(28,30,34,192) ); // nvgFillColor(vg, nvgRGBA(0,0,0,128) ); nvgFill(vg); // Drop shadow shadowPaint = nvgBoxGradient(vg, x,y+2, w,h, cornerRadius*2, 10, 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); // Header headerPaint = nvgLinearGradient(vg, x,y,x,y+15, nvgRGBA(255,255,255,8), nvgRGBA(0,0,0,16) ); nvgBeginPath(vg); nvgRoundedRect(vg, x+1,y+1, w-2,30, cornerRadius-1); nvgFillPaint(vg, headerPaint); nvgFill(vg); nvgBeginPath(vg); nvgMoveTo(vg, x+0.5f, y+0.5f+30); nvgLineTo(vg, x+0.5f+w-1, y+0.5f+30); nvgStrokeColor(vg, nvgRGBA(0,0,0,32) ); nvgStroke(vg); nvgFontSize(vg, 18.0f); nvgFontFace(vg, "sans-bold"); nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); nvgFontBlur(vg,2); nvgFillColor(vg, nvgRGBA(0,0,0,128) ); nvgText(vg, x+w/2,y+16+1, title, NULL); nvgFontBlur(vg,0); nvgFillColor(vg, nvgRGBA(220,220,220,160) ); nvgText(vg, x+w/2,y+16, title, NULL); nvgRestore(vg); }
static void drawPolygon(const float* coords, unsigned numCoords, float r, unsigned int col) { nvgBeginPath(vg::ctx); nvgFillColor(vg::ctx, nvgRGBA(col&0xff, (col>>8)&0xff, (col>>16)&0xff, (col>>24)&0xff)); nvgMoveTo(vg::ctx, coords[0], coords[1]); for (unsigned i = 1; i < numCoords; ++i) { nvgLineTo(vg::ctx, coords[i*2], coords[i*2+1]); } nvgFill(vg::ctx); }
void FPScounter::on_draw() { head = (head+1) % FPS_HISTORY_COUNT; float new_time = time(); values[head] = new_time - current_time; current_time = new_time; size_t i, _head; float avg, w, h; avg = 0; _head = head; for (i = 0; i < 10; i++) { avg += values[head]; _head = (head+FPS_HISTORY_COUNT-1) % FPS_HISTORY_COUNT; } avg /= 10.0f; w = 200; h = 30; nvgBeginPath(vg); nvgRect(vg, x,y, w,h); nvgFillColor(vg, nvgRGBA(0,0,0,128)); nvgFill(vg); nvgBeginPath(vg); nvgMoveTo(vg, x, y+h); for (i = 0; i < FPS_HISTORY_COUNT; i++) { float v = 1.0f / (0.00001f + values[(head+i) % FPS_HISTORY_COUNT]); if (v > 80.0f) v = 80.0f; float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; float vy = y + h - ((v / 80.0f) * h); nvgLineTo(vg, vx, vy); } nvgLineTo(vg, x+w, y+h); nvgFillColor(vg, nvgRGBA(255,192,0,128)); nvgFill(vg); label.setText(std::to_string(1.f/avg) + " FPS"); label.setPosition(x+w-5, y+h/2); // nvgFontSize(vg, 18.0f); // nvgFontFace(vg, "sans"); // nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); // nvgFillColor(vg, nvgRGBA(240,240,240,255)); // sprintf(str, "%.2f FPS", 1.0f / avg); // nvgText(vg, x+w-5,y+h/2, str, NULL); }
void Render() override { nvgBeginPath(GNvg); if (EdgePainter.Points.size() >= 4) { glm::vec2 temp = camera.WorldToScreen(glm::vec2(EdgePainter.Points[0], EdgePainter.Points[1])); nvgMoveTo(GNvg, temp[0], temp[1]); for (int i = 2; i < EdgePainter.Points.size(); i += 2) { temp = camera.WorldToScreen(glm::vec2(EdgePainter.Points[i], EdgePainter.Points[i + 1])); nvgLineTo(GNvg, temp[0], temp[1]); } } nvgStrokeColor(GNvg, nvgRGB(255, 255, 255)); nvgStrokeWidth(GNvg, 5); nvgStroke(GNvg); }
void Caret::draw(NVGcontext *ctx, float lineh, Vector2i offset) { //std::cout << "Cursor("<< mCursorPos.x()<< ","<< mCursorPos.y() <<")" << std::endl; if(isVisible()) { //float caretx = cursorIndex2Position(mCursorPos.x(), textBound[2], glyphs, nglyphs); //mPosition = getCursorPosition(ctx, mCursorPos, lineh); // draw cursor nvgBeginPath(ctx); nvgMoveTo(ctx, offset.x() + mPos.x(), offset.y()+ mPos.y() ); nvgLineTo(ctx, offset.x() + mPos.x(), offset.y()+ mPos.y()+ lineh ); nvgStrokeColor(ctx, nvgRGBA(255, 192, 0, 255)); nvgStrokeWidth(ctx, 1.0f); nvgStroke(ctx); } if(mSelectionState) { // draw selection int linew = mConsole->mSize.x(); nvgBeginPath(ctx); nvgFillColor(ctx, nvgRGBA(255, 255, 255, 80)); if(mIdx.y() == mSelectionIdx.y()) { int x = std::min(mPos.x(),mSelectionPos.x()); x += offset.x(); nvgRect(ctx, x, offset.y()+ mPos.y(), std::abs(mSelectionPos.x()-mPos.x()), lineh); } else if(mIdx.y() > mSelectionIdx.y()) { nvgRect(ctx, offset.x()+mSelectionPos.x(), offset.y()+ mSelectionPos.y(), linew-mSelectionPos.x(), lineh); if(mIdx.y()-mSelectionIdx.y()>1) nvgRect(ctx, offset.x(), offset.y()+ mSelectionPos.y()+lineh, linew, mPos.y()-mSelectionPos.y()-lineh); nvgRect(ctx, offset.x(), offset.y()+ mPos.y(), mPos.x(), lineh); } else { nvgRect(ctx, offset.x(), offset.y()+ mSelectionPos.y(), mSelectionPos.x(), lineh); if(mSelectionIdx.y()-mIdx.y()>1) nvgRect(ctx, offset.x(), offset.y()+ mPos.y()+lineh, linew, mSelectionPos.y()-mPos.y()-lineh); nvgRect(ctx, offset.x()+mPos.x(), offset.y()+ mPos.y(), linew-mPos.x(), lineh); } nvgFill(ctx); } }
void draw<vec_field_t>(vec_field_t& vf, NVGcolor& color) { vf.foreach_element([&](size_t i, size_t j, vec_t& v){ vec_t pos = vf.get_coordinates(i, j), to = pos + v; nvgBeginPath(vg); nvgCircle(vg, pos.x, pos.y, .2); nvgFillColor(vg, color); nvgFill(vg); nvgBeginPath(vg); nvgMoveTo(vg, pos.x, pos.y); nvgLineTo(vg, to.x, to.y); nvgStrokeColor(vg, color); nvgStrokeWidth(vg, one_pixel); nvgStroke(vg); }); }
void drawWidths(struct NVGcontext* vg, float x, float y, float width) { nvgSave(vg); nvgStrokeColor(vg, nvgRGBA(0,0,0,255) ); for (uint32_t ii = 0; ii < 20; ++ii) { float w = (ii+0.5f)*0.1f; nvgStrokeWidth(vg, w); nvgBeginPath(vg); nvgMoveTo(vg, x,y); nvgLineTo(vg, x+width,y+width*0.3f); nvgStroke(vg); y += 10; } nvgRestore(vg); }
void GraphNodeLink::draw(NVGcontext* ctx) { auto sourceSize = mSource->size().cast<float>(); Eigen::Vector2i inputPosition( mSource->absolutePosition().x() - mParent->absolutePosition().x() + (sourceSize.x() * 0.5f), mSource->absolutePosition().y() - mParent->absolutePosition().y() + (sourceSize.y() * 0.5f) ); Eigen::Vector2i outputPosition(Eigen::Vector2i::Zero()); if (hasTarget()) { // Get relative position of parent (node) of the target (sink) Eigen::Vector2i delta = mSink->parent()->absolutePosition() - mSink->parent()->position(); delta.x() -= (sourceSize.x() * 0.5f); delta.y() -= (sourceSize.y() * 0.5f); outputPosition = mSink->absolutePosition() - delta; } else { Eigen::Vector2i offset = mSource->absolutePosition() - mParent->absolutePosition(); Eigen::Vector2i delta = mTargetPosition - mSource->position(); outputPosition = offset + delta; } Eigen::Vector2i positionDiff = outputPosition - inputPosition; NVGcontext* vg = ctx; nvgStrokeColor(vg, nvgRGBA(131, 148, 150, 255)); nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgMoveTo( vg, inputPosition.x(), inputPosition.y() ); nvgQuadTo(vg, 1.2 * positionDiff.x(), positionDiff.y(), outputPosition.x(), outputPosition.y() ); nvgStroke(vg); Widget::draw(ctx); }
void renderFrame() { currentRotation = currentRotation*0.9f + rotation * 0.1f; glStencilMask(0xff); checkGlError("glStencilMask"); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); checkGlError("glClear"); nvgBeginFrame(vg, w, h, w/h); nvgBeginPath(vg); nvgMoveTo(vg, verticeX(90.f), verticeY(90.f)); nvgLineTo(vg, verticeX(90.f + 120.0f), verticeY(90.0f + 120.0f)); nvgLineTo(vg, verticeX(90.f + 240.f), verticeY(90.0f + 240.0f) ); nvgClosePath(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255)); nvgFill(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255)); nvgEndFrame(vg); }
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 OGUIFileBrowser::draw() { // ToDo (damiles): Create scroll for more files in window if (_is_file_browser_visible) { NVGcontext *vg = (NVGcontext *) _window->vg; nvgBeginPath(vg); nvgRect(vg, 0, 0, _window->getWindowWidth(), _window->getWindowHeight()); nvgFillColor(vg, nvgRGBA(28, 30, 34, 255)); nvgFill(vg); // sep line nvgBeginPath(vg); nvgMoveTo(vg, 200, 40); nvgLineTo(vg, 200, _window->getWindowHeight()); nvgFillColor(vg, nvgRGBA(0,0,0,255)); nvgFill(vg); nvgBeginPath(vg); nvgMoveTo(vg, 0, 40); nvgLineTo(vg, _window->getWindowWidth(), 40); nvgFillColor(vg, nvgRGBA(0,0,0,255)); nvgFill(vg); nvgBeginPath(vg); nvgMoveTo(vg, 200, _window->getWindowHeight()-40); nvgLineTo(vg, _window->getWindowWidth(), _window->getWindowHeight()-40); nvgFillColor(vg, nvgRGBA(0,0,0,255)); nvgFill(vg); // Draw accept and cancel buttons if(drawBasicButton(vg, this->_window, "Accept", _window->getWindowWidth()-100, _window->getWindowHeight()-30, 90, 20, _window->mouse_x, _window->mouse_y)){ _is_file_browser_visible=0; } if(drawBasicButton(vg, this->_window, "Close", _window->getWindowWidth()-200, _window->getWindowHeight()-30, 90, 20, _window->mouse_x, _window->mouse_y)){ _file_browser_result= NULL; _is_file_browser_visible=0; } // Draw de devices we found drawHeader(vg, "System", 0, 40, 200); // Draw system files int x=10; int y=75; for(int i=0; i<_system.size(); i++){ OGUIFile *file= _system.at(i); if( file->draw(vg, x, y, _window->mouse_x, _window->mouse_y) ){ // is clicked _file_browser_result= file; if(_file_browser_result!=NULL) { if (_file_browser_result->_is_dir && _actual_folder.compare(_file_browser_result->_path) != 0) { readFolder(_file_browser_result->_path); _actual_folder= _file_browser_result->_path; _file_browser_result = NULL; } } } y+=22; } // Draw files x=210; y=50; int max_height= _window->getWindowHeight()-80; for(int i=0; i<_file_list.size(); i++){ OGUIFile *file= _file_list.at(i); if( file->draw(vg, x, y, _window->mouse_x, _window->mouse_y) ){ // is clicked _file_browser_result= file; if(_file_browser_result!=NULL) { if (_file_browser_result->_is_dir && _actual_folder.compare(_file_browser_result->_path) != 0) { readFolder(_file_browser_result->_path); _actual_folder= _file_browser_result->_path; _file_browser_result = NULL; } } } y+=22; if(y>=max_height){ x+=202; y=50; } } // Show icon in header nvgFontSize(vg, 16.0f); nvgFontFace(vg, "icons"); nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_TOP); nvgFillColor(vg, nvgRGBA(0,0,0,255)); nvgText(vg, 10, 11, "\uF115", NULL); nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); nvgText(vg, 11, 13, "\uF115", NULL); nvgFillColor(vg, nvgRGBA(255,255,255,255)); // show path in header nvgFontSize(vg, 18.0f); nvgFontFace(vg, "sans-bold"); nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); nvgFillColor(vg, nvgRGBA(0, 0, 0, 255)); nvgText(vg, 35, 10, resolved_path, NULL); nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); nvgText(vg, 36, 12, resolved_path, NULL); if(_file_browser_result!=NULL) { if (_file_browser_result->_is_dir == false) { // show file in footer nvgFontSize(vg, 18.0f); nvgFontFace(vg, "sans-bold"); nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); nvgFillColor(vg, nvgRGBA(0, 0, 0, 255)); nvgText(vg, 209, _window->getWindowHeight()-32, _file_browser_result->_file_name.c_str(), NULL); nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); nvgText(vg, 210, _window->getWindowHeight()-30, _file_browser_result->_file_name.c_str(), NULL); // Draw preview if its image if(_file_browser_result->isImage()){ x=0; y=_window->getWindowHeight()-200; drawHeader(vg, "Preview", 0, y-30, 200); int w=200; int h=200; NVGpaint bg; // Box bg = nvgBoxGradient(vg, x+1,y+1+1.5f, w-2,h-2, 3,4, nvgRGBA(255,255,255,32), nvgRGBA(32,32,32,32)); nvgBeginPath(vg); nvgRoundedRect(vg, x+1,y+1, w-2,h-2, 4-1); nvgFillPaint(vg, bg); nvgFill(vg); nvgBeginPath(vg); nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, 4-0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,48)); nvgStroke(vg); // Image preview if(_preview_image==-1){ _preview_image= nvgCreateImageRGBA(vg, 150, 150, 0, _file_browser_result->getPreview()); }else{ nvgUpdateImage(vg, _preview_image, _file_browser_result->getPreview()); } NVGpaint imgPaint = nvgImagePattern(vg, 25, y+25, 150, 150, 0, _preview_image, 1); nvgBeginPath(vg); nvgRect(vg, 25, y+25, 150,150); nvgFillPaint(vg, imgPaint); nvgFill(vg); } } } } }
void NanoVG::moveTo( float x, float y ) { nvgMoveTo( m_context(), 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::moveTo(float x, float y) { nvgMoveTo(m_context, x, y); }
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); nvgScissor(ctx, mPos.x(), mPos.y(), mSize.x(), 0.5f); nvgStroke(ctx); nvgResetScissor(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 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 drawParagraph(struct NVGcontext* vg, float x, float y, float width, float height, float mx, float my) { struct NVGtextRow rows[3]; struct NVGglyphPosition glyphs[100]; const char* text = "This is longer chunk of text.\n \n Would have used lorem ipsum but she was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party."; const char* start; const char* end; int nrows, i, nglyphs, j, lnum = 0; float lineh; float caretx, px; float bounds[4]; float gx = 0.0f, gy = 0.0f; int gutter = 0; NVG_NOTUSED(height); nvgSave(vg); nvgFontSize(vg, 18.0f); nvgFontFace(vg, "sans"); nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); nvgTextMetrics(vg, NULL, NULL, &lineh); // The text break API can be used to fill a large buffer of rows, // or to iterate over the text just few lines (or just one) at a time. // The "next" variable of the last returned item tells where to continue. start = text; end = text + strlen(text); for (nrows = nvgTextBreakLines(vg, start, end, width, rows, 3); 0 != nrows; nrows = nvgTextBreakLines(vg, start, end, width, rows, 3) ) { for (i = 0; i < nrows; i++) { struct NVGtextRow* row = &rows[i]; int hit = mx > x && mx < (x+width) && my >= y && my < (y+lineh); nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(255,255,255,hit?64:8) ); nvgRect(vg, x, y, row->width, lineh); nvgFill(vg); nvgFillColor(vg, nvgRGBA(255,255,255,255) ); nvgText(vg, x, y, row->start, row->end); if (hit) { caretx = (mx < x+row->width/2) ? x : x+row->width; px = x; nglyphs = nvgTextGlyphPositions(vg, x, y, row->start, row->end, glyphs, 100); for (j = 0; j < nglyphs; j++) { float x0 = glyphs[j].x; float x1 = (j+1 < nglyphs) ? glyphs[j+1].x : x+row->width; float tgx = x0 * 0.3f + x1 * 0.7f; if (mx >= px && mx < tgx) caretx = glyphs[j].x; px = tgx; } nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255) ); nvgRect(vg, caretx, y, 1, lineh); nvgFill(vg); gutter = lnum+1; gx = x - 10; gy = y + lineh/2; } lnum++; y += lineh; } // Keep going... start = rows[nrows-1].next; } if (gutter) { char txt[16]; bx::snprintf(txt, sizeof(txt), "%d", gutter); nvgFontSize(vg, 13.0f); nvgTextAlign(vg, NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); nvgTextBounds(vg, gx,gy, txt, NULL, bounds); nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255) ); nvgRoundedRect(vg , bx::fround(bounds[0])-4.0f , bx::fround(bounds[1])-2.0f , bx::fround(bounds[2]-bounds[0])+8.0f , bx::fround(bounds[3]-bounds[1])+4.0f , (bx::fround(bounds[3]-bounds[1])+4.0f)/2.0f-1.0f ); nvgFill(vg); nvgFillColor(vg, nvgRGBA(32,32,32,255) ); nvgText(vg, gx,gy, txt, NULL); } y += 20.0f; nvgFontSize(vg, 13.0f); nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); nvgTextLineHeight(vg, 1.2f); nvgTextBoxBounds(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL, bounds); nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(220,220,220,255) ); nvgRoundedRect(vg , bx::fround(bounds[0]-2.0f) , bx::fround(bounds[1]-2.0f) , bx::fround(bounds[2]-bounds[0])+4.0f , bx::fround(bounds[3]-bounds[1])+4.0f , 3.0f ); px = float( (int)( (bounds[2]+bounds[0])/2) ); nvgMoveTo(vg, px,bounds[1] - 10); nvgLineTo(vg, px+7,bounds[1]+1); nvgLineTo(vg, px-7,bounds[1]+1); nvgFill(vg); nvgFillColor(vg, nvgRGBA(0,0,0,220) ); nvgTextBox(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL); nvgRestore(vg); }