diff --git a/apps/test.cpp b/apps/test.cpp index a74d6ad..100d9a8 100644 --- a/apps/test.cpp +++ b/apps/test.cpp @@ -131,6 +131,9 @@ int TestCanvasMessage(EsElement *, EsMessage *message) { size_t dataBytes; const void *data = EsEmbeddedFileGet("test", -1, &dataBytes); if (data) EsDrawVectorFile(message->painter, EsPainterBoundsClient(message->painter), data, dataBytes); + + uint32_t cornerRadii[4] = { 10, 20, 30, 40 }; + EsDrawRoundedRectangle(message->painter, EsPainterBoundsClient(message->painter), 0xFF00FF00, 0xFFFF00FF, ES_RECT_1(10), cornerRadii); } else if (message->type == ES_MSG_GET_WIDTH) { message->measure.width = 256; } else if (message->type == ES_MSG_GET_HEIGHT) { diff --git a/desktop/os.header b/desktop/os.header index 7b8f90f..3b8ea8f 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -1359,17 +1359,6 @@ struct EsTextSelection { uint32_t foreground, background; }; -function_pointer uint32_t EsFragmentShaderCallback(int x, int y, struct EsStyledBox *box); - -struct EsStyledBox { - EsRectangle bounds, clip; - uint32_t backgroundColor, backgroundColor2; - EsFragmentShaderCallback fragmentShader; - uint32_t borderColor; - EsRectangle borders; - int cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomLeft, cornerRadiusBottomRight; -}; - struct EsArena { // Arenas are not thread-safe! // You can use different arenas in different threads, though. @@ -2067,6 +2056,7 @@ function void EsDrawContent(EsPainter *painter, EsElement *element, EsRectangle function void EsDrawInvert(EsPainter *painter, EsRectangle bounds); function void EsDrawLine(EsPainter *painter, float *vertices, size_t vertexCount, EsDeviceColor color, float width, uint32_t flags); // Vertices are pairs of x,y coordinates. function void EsDrawRectangle(EsPainter *painter, EsRectangle bounds, EsDeviceColor mainColor, EsDeviceColor borderColor, EsRectangle borderSize); +function void EsDrawRoundedRectangle(EsPainter *painter, EsRectangle bounds, EsDeviceColor mainColor, EsDeviceColor borderColor, EsRectangle borderSize, const uint32_t *cornerRadii); // Must pass 4 corner radii in the order top left, top right, bottom left, bottom right. function bool EsDrawStandardIcon(EsPainter *painter, uint32_t id, int size, EsRectangle region, EsDeviceColor color); function void EsDrawPaintTarget(EsPainter *painter, EsPaintTarget *source, EsRectangle destinationRegion, EsRectangle sourceRegion, uint8_t alpha); function void EsDrawText(EsPainter *painter, EsTextPlan *plan, EsRectangle bounds, EsRectangle *clip = ES_NULL, EsTextSelection *selectionProperties = ES_NULL); diff --git a/desktop/theme.cpp b/desktop/theme.cpp index ae1abd3..135d4ef 100644 --- a/desktop/theme.cpp +++ b/desktop/theme.cpp @@ -67,6 +67,10 @@ #define THEME_CHILD_TYPE_NONE (3) #define THEME_CHILD_TYPE_HORIZONTAL (1 << 4) +#ifndef IN_DESIGNER +typedef uint32_t (*EsFragmentShaderCallback)(int x, int y, struct EsStyledBox *box); +#endif + typedef enum ThemeCursor { THEME_CURSOR_NORMAL, THEME_CURSOR_TEXT, @@ -2182,6 +2186,15 @@ bool UIStyle::IsRegionCompletelyOpaque(EsRectangle region, int width, int height && region.t >= opaqueInsets.t && region.b < height - opaqueInsets.b; } +struct EsStyledBox { + EsRectangle bounds, clip; + uint32_t backgroundColor, backgroundColor2; + EsFragmentShaderCallback fragmentShader; + uint32_t borderColor; + EsRectangle borders; + int cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomLeft, cornerRadiusBottomRight; +}; + void DrawStyledBox(EsPainter *painter, EsStyledBox box) { ThemeLayer layer = {}; ThemeLayerBox layerBox = {}; @@ -2223,4 +2236,24 @@ void DrawStyledBox(EsPainter *painter, EsStyledBox box) { ThemeDrawBox(painter, box.bounds, &data, 1, &layer, {}, THEME_CHILD_TYPE_ONLY); } +void EsDrawRoundedRectangle(EsPainter *painter, EsRectangle bounds, EsDeviceColor mainColor, EsDeviceColor borderColor, EsRectangle borderSize, const uint32_t *cornerRadii) { + ThemeLayer layer = {}; + uint8_t info[sizeof(ThemeLayerBox) + sizeof(ThemePaintSolid) * 2]; + + ThemeLayerBox *infoBox = (ThemeLayerBox *) info; + infoBox->borders = { (int8_t) borderSize.l, (int8_t) borderSize.r, (int8_t) borderSize.t, (int8_t) borderSize.b }; + infoBox->corners = { (int8_t) cornerRadii[0], (int8_t) cornerRadii[1], (int8_t) cornerRadii[2], (int8_t) cornerRadii[3] }; + infoBox->mainPaintType = THEME_PAINT_SOLID; + infoBox->borderPaintType = THEME_PAINT_SOLID; + + ThemePaintSolid *infoMain = (ThemePaintSolid *) (infoBox + 1); + infoMain->color = mainColor; + + ThemePaintSolid *infoBorder = (ThemePaintSolid *) (infoMain + 1); + infoBorder->color = borderColor; + + EsBuffer data = { .in = (const uint8_t *) &info, .bytes = sizeof(info) }; + ThemeDrawBox(painter, bounds, &data, 1, &layer, {}, THEME_CHILD_TYPE_ONLY); +} + #endif diff --git a/util/api_table.ini b/util/api_table.ini index 04fdc76..5d03d9d 100644 --- a/util/api_table.ini +++ b/util/api_table.ini @@ -439,3 +439,4 @@ EsUserTaskIsRunning=437 EsTextboxSetFont=438 EsTextboxSetTextSize=439 EsRectangleLinearInterpolate=440 +EsDrawRoundedRectangle=441