diff --git a/desktop/gui.cpp b/desktop/gui.cpp index b95c70f..37a22e7 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -4177,22 +4177,69 @@ struct ColorPicker { } }; +struct StyledBox { + EsRectangle bounds; + uint32_t backgroundColor, backgroundColor2, borderColor; + uint32_t cornerRadius, borderSize; + EsFragmentShaderCallback fragmentShader; +}; + +void DrawStyledBox(EsPainter *painter, StyledBox box) { + ThemeLayer layer = {}; + ThemeLayerBox layerBox = {}; + EsBuffer data = {}; + + layerBox.borders = { (int8_t) box.borderSize, (int8_t) box.borderSize, (int8_t) box.borderSize, (int8_t) box.borderSize }; + layerBox.corners = { (int8_t) box.cornerRadius, (int8_t) box.cornerRadius, (int8_t) box.cornerRadius, (int8_t) box.cornerRadius }; + layerBox.mainPaintType = THEME_PAINT_SOLID; + layerBox.borderPaintType = THEME_PAINT_SOLID; + + uint8_t info[sizeof(ThemeLayerBox) + sizeof(ThemePaintCustom) + sizeof(ThemePaintSolid) * 2]; + + if (box.fragmentShader) { + ThemeLayerBox *infoBox = (ThemeLayerBox *) info; + ThemePaintCustom *infoMain = (ThemePaintCustom *) (infoBox + 1); + ThemePaintSolid *infoBorder = (ThemePaintSolid *) (infoMain + 1); + + *infoBox = layerBox; + infoBox->mainPaintType = THEME_PAINT_CUSTOM; + infoMain->callback = box.fragmentShader; + infoBorder->color = box.borderColor; + + data.in = (const uint8_t *) &info; + data.bytes = sizeof(info); + data.context = &box; + } else { + ThemeLayerBox *infoBox = (ThemeLayerBox *) info; + ThemePaintSolid *infoMain = (ThemePaintSolid *) (infoBox + 1); + ThemePaintSolid *infoBorder = (ThemePaintSolid *) (infoMain + 1); + + *infoBox = layerBox; + infoMain->color = box.backgroundColor; + infoBorder->color = box.borderColor; + + data.in = (const uint8_t *) &info; + data.bytes = sizeof(info); + } + + ThemeDrawBox(painter, box.bounds, &data, 1, &layer, {}, THEME_CHILD_TYPE_ONLY); +} + int ProcessColorChosenPointMessage(EsElement *element, EsMessage *message) { ColorPicker *picker = (ColorPicker *) element->userData.p; if (message->type == ES_MSG_PAINT) { EsRectangle bounds = EsPainterBoundsInset(message->painter); - EsStyledBox box = {}; + StyledBox box = {}; box.bounds = bounds; - box.clip = message->painter->clip; box.borderColor = 0xFFFFFFFF; box.backgroundColor = picker->color | 0xFF000000; box.backgroundColor2 = picker->color | ((uint32_t) (255.0f * picker->opacity) << 24); - box.borders = ES_RECT_1(2); - box.cornerRadiusTopLeft = box.cornerRadiusTopRight = box.cornerRadiusBottomLeft = box.cornerRadiusBottomRight = Width(box.bounds) / 2; + box.borderSize = 2; + box.cornerRadius = Width(box.bounds) / 2; if (picker->opacity < 1 && picker->host.hasOpacity) { - box.fragmentShader = [] (int x, int y, EsStyledBox *box) -> uint32_t { + box.fragmentShader = [] (int x, int y, StyledBox *box) -> uint32_t { // TODO Move the alpha background as the chosen point moves. return EsColorBlend(((((x - 2) >> 3) ^ ((y + 5) >> 3)) & 1) ? 0xFFFFFFFF : 0xFFC0C0C0, box->backgroundColor2, false); @@ -4553,10 +4600,9 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) { if (message->type == ES_MSG_PAINT) { EsRectangle bounds = EsPainterBoundsInset(message->painter); - EsStyledBox box = {}; + StyledBox box = {}; box.bounds = bounds; - box.clip = message->painter->clip; - box.borders = ES_RECT_1(1); + box.borderSize = 1; if (well->indeterminate) { box.backgroundColor = 0; @@ -4567,7 +4613,7 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) { box.borderColor = EsColorBlend(well->color | 0xFF000000, 0x40000000, false); if ((well->flags & ES_COLOR_WELL_HAS_OPACITY) && ((well->color & 0xFF000000) != 0xFF000000)) { - box.fragmentShader = [] (int x, int y, EsStyledBox *box) -> uint32_t { + box.fragmentShader = [] (int x, int y, StyledBox *box) -> uint32_t { return EsColorBlend(((((x - box->bounds.l - 4) >> 3) ^ ((y - box->bounds.t + 2) >> 3)) & 1) ? 0xFFFFFFFF : 0xFFC0C0C0, box->backgroundColor, false); }; diff --git a/desktop/theme.cpp b/desktop/theme.cpp index 135d4ef..b8dce35 100644 --- a/desktop/theme.cpp +++ b/desktop/theme.cpp @@ -67,10 +67,6 @@ #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, @@ -130,6 +126,10 @@ typedef struct ThemePaintRadialGradient { // Followed by gradient stops. } ThemePaintRadialGradient; +#ifndef IN_DESIGNER +typedef uint32_t (*EsFragmentShaderCallback)(int x, int y, struct StyledBox *box); +#endif + typedef struct ThemePaintCustom { #ifndef IN_DESIGNER EsFragmentShaderCallback callback; @@ -453,7 +453,7 @@ void ThemeFillRectangle(EsPainter *painter, EsRectangle bounds, ThemePaintData p uint32_t *b = bits + bounds.l + y * width; do { - BlendPixel(b, paint.custom->callback(x, y, (EsStyledBox *) gradient->context), painter->target->fullAlpha); + BlendPixel(b, paint.custom->callback(x, y, (StyledBox *) gradient->context), painter->target->fullAlpha); x++, b++; } while (x < bounds.r); } @@ -525,7 +525,7 @@ void ThemeFillCorner(EsPainter *painter, EsRectangle bounds, int cx, int cy, #ifndef IN_DESIGNER } else if (mainPaint.type == THEME_PAINT_CUSTOM) { mainColor = mainPaint.custom->callback((i >> STYLE_CORNER_OVERSAMPLING) - mainGradient->ox + bounds.l, - (j >> STYLE_CORNER_OVERSAMPLING) - mainGradient->oy + bounds.t, (EsStyledBox *) mainGradient->context); + (j >> STYLE_CORNER_OVERSAMPLING) - mainGradient->oy + bounds.t, (StyledBox *) mainGradient->context); #endif } else { mainColor = 0; @@ -2186,56 +2186,6 @@ 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 = {}; - EsBuffer data = {}; - - layerBox.borders = { (int8_t) box.borders.l, (int8_t) box.borders.r, (int8_t) box.borders.t, (int8_t) box.borders.b }; - layerBox.corners = { (int8_t) box.cornerRadiusTopLeft, (int8_t) box.cornerRadiusTopRight, (int8_t) box.cornerRadiusBottomLeft, (int8_t) box.cornerRadiusBottomRight }; - layerBox.mainPaintType = THEME_PAINT_SOLID; - layerBox.borderPaintType = THEME_PAINT_SOLID; - - uint8_t info[sizeof(ThemeLayerBox) + sizeof(ThemePaintCustom) + sizeof(ThemePaintSolid) * 2]; - - if (box.fragmentShader) { - ThemeLayerBox *infoBox = (ThemeLayerBox *) info; - ThemePaintCustom *infoMain = (ThemePaintCustom *) (infoBox + 1); - ThemePaintSolid *infoBorder = (ThemePaintSolid *) (infoMain + 1); - - *infoBox = layerBox; - infoBox->mainPaintType = THEME_PAINT_CUSTOM; - infoMain->callback = box.fragmentShader; - infoBorder->color = box.borderColor; - - data.in = (const uint8_t *) &info; - data.bytes = sizeof(info); - data.context = &box; - } else { - ThemeLayerBox *infoBox = (ThemeLayerBox *) info; - ThemePaintSolid *infoMain = (ThemePaintSolid *) (infoBox + 1); - ThemePaintSolid *infoBorder = (ThemePaintSolid *) (infoMain + 1); - - *infoBox = layerBox; - infoMain->color = box.backgroundColor; - infoBorder->color = box.borderColor; - - data.in = (const uint8_t *) &info; - data.bytes = sizeof(info); - } - - 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];