/* * Part of LaGUI demonstration programs * Copyright (C) 2022-2023 Wu Yiming * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define NANOVG_GL3_IMPLEMENTATION #include "la_5.h" extern LA MAIN; extern tnsMain* T; void MyPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){ laColumn* c=laFirstColumn(uil); laShowCanvas(uil,c,0,"tns","my_nanovg_canvas",-1); } typedef struct MyCanvas{ laCanvasExtra e; NVGcontext* c; }MyCanvas; /* From NanoVG */ void drawColorwheel(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); 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 my_CanvasInit(laUiItem *ui){ MyCanvas* mye=memAcquire(sizeof(MyCanvas)); ui->Extra=mye; la_CanvasInit(ui); mye->c=nvgCreateGL3(NVG_STENCIL_STROKES|NVG_DEBUG|NVG_ANTIALIAS); } void my_CanvasDestroy(laUiItem *ui){ MyCanvas* mye=ui->Extra; nvgDeleteGL3(mye->c); la_CanvasDestroy(ui); } void my_CanvasDrawCanvas(laBoxedTheme *bt, void *unused_c, laUiItem* ui){ laCanvasExtra* e=ui->Extra; MyCanvas* mye=e; int W, H; W = ui->R - ui->L; H = ui->B - ui->U; tnsFlush(); if (!e->OffScr || e->OffScr->pColor[0]->Height != ui->B - ui->U || e->OffScr->pColor[0]->Width != ui->R - ui->L){ if (e->OffScr) tnsDelete2DOffscreen(e->OffScr); e->OffScr = tnsCreate2DOffscreen(GL_RGBA8, W, H, 0, 0, 1); } tnsDrawToOffscreen(e->OffScr,1,0); tnsViewportWithScissor(0, 0, W, H); tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix(); tnsOrtho(e->PanX - W * e->ZoomX / 2, e->PanX + W * e->ZoomX / 2, e->PanY - e->ZoomY * H / 2, e->PanY + e->ZoomY * H / 2, 100, -100); tnsClearColor(0,0,0,1); tnsClearAll(); NVGcontext* vg=mye->c; nvgBeginFrame(vg,W,H,1); drawColorwheel(vg,0,0,W,H,1); nvgEndFrame(vg); tnsRestoreFromNanoVG(); } void my_CanvasDrawOverlay(laUiItem* ui,int h){ laCanvasExtra *e = ui->Extra; laBoxedTheme *bt = (*ui->Type->Theme); tnsUseImmShader(); tnsEnableShaderv(T->immShader); tnsUniformColorMode(T->immShader,0); tnsUniformOutputColorSpace(T->immShader, 0); tnsDraw2DTextureDirectly(e->OffScr->pColor[0], ui->L, ui->U, ui->R - ui->L, ui->B - ui->U); tnsFlush(); la_CanvasDefaultOverlay(ui, h); } int main(int argc, char *argv[]){ laGetReady(); transSetLanguage("zh-CN"); laCanvasTemplate* ct=laRegisterCanvasTemplate("my_nanovg_canvas", 0, 0, my_CanvasDrawCanvas, my_CanvasDrawOverlay, my_CanvasInit, my_CanvasDestroy); laRegisterUiTemplate("nanovg_panel","NanoVG Panel", MyPanel,0,0,"NanoVG Demonstration", 0,0,0); laWindow* w = laDesignWindow(-1,-1,600,600); laLayout* l = laDesignLayout(w,"My Layout"); laCreatePanel(l->FirstBlock,"nanovg_panel"); laStartWindow(w); laMainLoop(); return 0; }