Exemplo n.º 1
0
void TextNode::renderItself(RenderContext& renderContext)
{
    NVGcontext& nanoVgContext = renderContext.getNanoVgContext();
    nvgSave(&nanoVgContext);

    setupContext(nanoVgContext);

    Color finalColor = mFontColor.getBlendedColor(renderContext.getBlendColors());
    nvgFillColor(&nanoVgContext, nvgRGBAf(finalColor.getRed(), finalColor.getGreen(),
            finalColor.getBlue(), finalColor.getAlpha()));

    for(const Text& text : mTexts)
    {
        const char* charArray = text.getString().getCharArray();
        float positionX = text.getPosition().getX();
        float positionY = text.getPosition().getY();
        if(isPositive(text.getBoxWidth()))
        {
            nvgTextBox(&nanoVgContext, positionX, positionY, text.getBoxWidth(), charArray, nullptr);
        }
        else
        {
            nvgText(&nanoVgContext, positionX, positionY, charArray, nullptr);
        }
    }

    nvgRestore(&nanoVgContext);

    Node::renderItself(renderContext);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
void QNanoPainter::fillText(const QString &text, const QRectF &rect)
{
    float x = rect.x();
    float y = rect.y();
    _checkAlignPixelsText(&x, &y);
    _checkFont();
    nvgTextBox(nvgCtx(), x, y, rect.width(), text.toUtf8().constData(), nullptr);
}
Exemplo n.º 4
0
void QNanoPainter::fillText(const QString &text, float x, float y, float maxWidth)
{
    _checkAlignPixelsText(&x, &y);
    _checkFont();
    if (maxWidth < 0) {
        nvgText(nvgCtx(), x, y, text.toUtf8().constData(), nullptr);
    } else {
        nvgTextBox(nvgCtx(), x, y, maxWidth, text.toUtf8().constData(), nullptr);
    }
}
Exemplo n.º 5
0
void Label::draw(NVGcontext *ctx) {
    Widget::draw(ctx);
    nvgFontFace(ctx, mFont.c_str());
    nvgFontSize(ctx, fontSize());
    nvgFillColor(ctx, mColor);
    if (mFixedSize.x() > 0) {
        nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
        nvgTextBox(ctx, mPos.x(), mPos.y(), mFixedSize.x(), mCaption.c_str(), nullptr);
    } else {
        nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
        nvgText(ctx, mPos.x(), mPos.y() + mSize.y() * 0.5f, mCaption.c_str(), nullptr);
    }
}
Exemplo n.º 6
0
void drawUI(NVGcontext *vg, int item, int corners) {
    const UIData *head = (const UIData *)uiGetHandle(item);
    UIrect rect = uiGetRect(item);
    if (uiGetState(item) == UI_FROZEN) {
        nvgGlobalAlpha(vg, BND_DISABLED_ALPHA);
    }
    if (head) {
        switch(head->subtype) {
            default: {
                testrect(vg,rect);
                drawUIItems(vg,item,corners);
            } break;
            case ST_HBOX: {
                drawUIItemsHbox(vg, item);
            } break;
            case ST_VBOX: {
                drawUIItemsVbox(vg, item);
            } break;
            case ST_PANEL: {
                bndBevel(vg,rect.x,rect.y,rect.w,rect.h);
                drawUIItems(vg,item,corners);
            } break;
            case ST_LABEL: {
                assert(head);
                const UIButtonData *data = (UIButtonData*)head;
                bndLabel(vg,rect.x,rect.y,rect.w,rect.h,
                    data->iconid,data->label);
            } break;
            case ST_BUTTON: {
                const UIButtonData *data = (UIButtonData*)head;
                bndToolButton(vg,rect.x,rect.y,rect.w,rect.h,
                        corners,(BNDwidgetState)uiGetState(item),
                    data->iconid,data->label);
            } break;
            case ST_CHECK: {
                const UICheckData *data = (UICheckData*)head;
                BNDwidgetState state = (BNDwidgetState)uiGetState(item);
                if (*data->option)
                    state = BND_ACTIVE;
                bndOptionButton(vg,rect.x,rect.y,rect.w,rect.h, state,
                    data->label);
            } break;
            case ST_RADIO:{
                const UIRadioData *data = (UIRadioData*)head;
                BNDwidgetState state = (BNDwidgetState)uiGetState(item);
                if (*data->value == item)
                    state = BND_ACTIVE;
                bndRadioButton(vg,rect.x,rect.y,rect.w,rect.h,
                        corners,state,
                    data->iconid,data->label);
            } break;
            case ST_SLIDER:{
                const UISliderData *data = (UISliderData*)head;
                BNDwidgetState state = (BNDwidgetState)uiGetState(item);
                static char value[32];
                sprintf(value,"%.0f%%",(*data->progress)*100.0f);
                bndSlider(vg,rect.x,rect.y,rect.w,rect.h,
                        corners,state,
                    *data->progress,data->label,value);
            } break;
            case ST_TEXT: {
                const UITextData *data = (UITextData*)head;
                BNDwidgetState state = (BNDwidgetState)uiGetState(item);
                int idx = strlen(data->text);
                bndTextField(vg,rect.x,rect.y,rect.w,rect.h,
                        corners,state, -1, data->text, idx, idx);
            } break;
            case ST_DEMOSTUFF: {
                draw_demostuff(vg, rect.x, rect.y, rect.w, rect.h);
            } break;
            case ST_RECT: {
                const UIRectData *data = (UIRectData*)head;
                if (rect.w && rect.h) {
                    BNDwidgetState state = (BNDwidgetState)uiGetState(item);
                    nvgSave(vg);
                    nvgStrokeColor(vg, nvgRGBAf(data->color.r,data->color.g,data->color.b,0.9f));
                    if (state != BND_DEFAULT) {
                        nvgFillColor(vg, nvgRGBAf(data->color.r,data->color.g,data->color.b,0.5f));
                    } else {
                        nvgFillColor(vg, nvgRGBAf(data->color.r,data->color.g,data->color.b,0.1f));
                    }
                    nvgStrokeWidth(vg,2);
                    nvgBeginPath(vg);
                    #if 0
                    nvgRect(vg,rect.x,rect.y,rect.w,rect.h);
                    #else
                    nvgRoundedRect(vg,rect.x,rect.y,rect.w,rect.h,3);
                    #endif
                    nvgFill(vg);
                    nvgStroke(vg);

                    if (state != BND_DEFAULT) {
                        nvgFillColor(vg, nvgRGBAf(0.0f,0.0f,0.0f,1.0f));
                        nvgFontSize(vg, 15.0f);
                        nvgBeginPath(vg);
                        nvgTextAlign(vg, NVG_ALIGN_TOP|NVG_ALIGN_CENTER);
                        nvgTextBox(vg, rect.x, rect.y+rect.h*0.3f, rect.w, data->label, NULL);
                    }

                    nvgRestore(vg);
                }
                nvgSave(vg);
                nvgIntersectScissor(vg, rect.x, rect.y, rect.w, rect.h);

                drawUIItems(vg,item,corners);

                nvgRestore(vg);
            } break;
        }
    } else {
        testrect(vg,rect);
        drawUIItems(vg,item,corners);
    }

    if (uiGetState(item) == UI_FROZEN) {
        nvgGlobalAlpha(vg, 1.0);
    }
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
int main()
{
	constexpr auto width = 1200u;
	constexpr auto height = 800u;

	// init ny app
	auto& backend = ny::Backend::choose();
	if(!backend.vulkan()) {
		dlg_error("ny backend has no vulkan support!");
		return 0;
	}

	auto ac = backend.createAppContext();

	// basic vpp init
	auto iniExtensions = ac->vulkanExtensions();
	iniExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
	vk::ApplicationInfo appInfo ("vpp-intro", 1, "vpp", 1, VK_API_VERSION_1_0);
	vk::InstanceCreateInfo instanceInfo;
	instanceInfo.pApplicationInfo = &appInfo;
	instanceInfo.enabledExtensionCount = iniExtensions.size();
	instanceInfo.ppEnabledExtensionNames = iniExtensions.data();

#ifdef WithLayers
	constexpr auto layer = "VK_LAYER_LUNARG_standard_validation";
	instanceInfo.enabledLayerCount = 1;
	instanceInfo.ppEnabledLayerNames = &layer;
#endif

	vpp::Instance instance(instanceInfo);

#ifdef WithLayers
	vpp::DebugCallback debugCallback(instance);
#endif

	// ny init
	auto run = true;

	auto listener = MyWindowListener {};
	listener.run = &run;

	auto vkSurface = vk::SurfaceKHR {};
	auto ws = ny::WindowSettings {};
	ws.surface = ny::SurfaceType::vulkan;
	ws.listener = &listener;
	ws.size = {width, height};
	ws.vulkan.instance = (VkInstance) instance.vkHandle();
	ws.vulkan.storeSurface = &(std::uintptr_t&) (vkSurface);
	auto wc = ac->createWindowContext(ws);

	// further vpp init
	const vpp::Queue* presentQueue;
	vpp::Device device(instance, vkSurface, presentQueue);
	vpp::Swapchain swapchain(device, vkSurface, {width, height}, {});

	// vvg setup
	auto nvgContext = vvg::createContext(swapchain);
	auto font = nvgCreateFont(nvgContext, "sans", "Roboto-Regular.ttf");

	using Clock = std::chrono::high_resolution_clock;
	auto lastFrameTimer = Clock::now();
	unsigned int framesCount = 0;
	std::string fpsString = "420 fps";

	// main loop
	while(run) {
		if(!ac->dispatchEvents())
			break;

		nvgBeginFrame(nvgContext, width, height, width / (float) height);

		nvgBeginPath(nvgContext);
		nvgMoveTo(nvgContext, 10, 10);
		nvgLineTo(nvgContext, 10, 400);
		nvgLineTo(nvgContext, 100, 400);
		nvgQuadTo(nvgContext, 100, 50, 400, 120);
		nvgLineTo(nvgContext, 450, 10);
		nvgClosePath(nvgContext);

		nvgFillColor(nvgContext, nvgRGBAf(0.5, 0.8, 0.7, 1.0));
		nvgFill(nvgContext);

		nvgBeginPath(nvgContext);
		nvgFontFaceId(nvgContext, font);
		nvgFontSize(nvgContext, 100.f);
		nvgFontBlur(nvgContext, .8f);
		nvgFillColor(nvgContext, nvgRGBAf(1.0, 1.0, 1.0, 1.0));
		nvgTextBox(nvgContext, 200, 200, width - 200, "Hello Vulkan Vector Graphics World", nullptr);

		nvgFontSize(nvgContext, 30.f);
		nvgFontBlur(nvgContext, .2f);
		nvgText(nvgContext, 10, height - 20, fpsString.c_str(), nullptr);

		nvgBeginPath(nvgContext);
		nvgRect(nvgContext, 700, 400, 300, 300);
		nvgPathWinding(nvgContext, NVG_HOLE);
		nvgRect(nvgContext, 750, 450, 50, 50);
		// auto paint = nvgRadialGradient(nvgContext, 750, 425,20, 50, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0));
		// auto paint = nvgRadialGradient(nvgContext, 0.0, 0.0, 0.2, 100.0, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0));
		auto paint = nvgLinearGradient(nvgContext, 700, 400, 800, 450, nvgRGB(0, 0, 200), nvgRGB(200, 200, 0));
		nvgFillPaint(nvgContext, paint);
		// nvgFillColor(nvgContext, nvgRGBA(200, 200, 0, 200));
		nvgClosePath(nvgContext);
		nvgFill(nvgContext);

		nvgEndFrame(nvgContext);

		// only refresh frame timer every second
		framesCount++;
		if(Clock::now() - lastFrameTimer >= std::chrono::seconds(1)) {
			fpsString = std::to_string(framesCount) + " fps";
			lastFrameTimer = Clock::now();
			framesCount = 0;
		}
	}

	vvg::destroyContext(*nvgContext);
}