cleanup DrawStyledBox

This commit is contained in:
nakst 2021-09-08 21:48:57 +01:00
parent 08e889c837
commit c1dc8d5894
2 changed files with 61 additions and 65 deletions

View File

@ -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) { int ProcessColorChosenPointMessage(EsElement *element, EsMessage *message) {
ColorPicker *picker = (ColorPicker *) element->userData.p; ColorPicker *picker = (ColorPicker *) element->userData.p;
if (message->type == ES_MSG_PAINT) { if (message->type == ES_MSG_PAINT) {
EsRectangle bounds = EsPainterBoundsInset(message->painter); EsRectangle bounds = EsPainterBoundsInset(message->painter);
EsStyledBox box = {}; StyledBox box = {};
box.bounds = bounds; box.bounds = bounds;
box.clip = message->painter->clip;
box.borderColor = 0xFFFFFFFF; box.borderColor = 0xFFFFFFFF;
box.backgroundColor = picker->color | 0xFF000000; box.backgroundColor = picker->color | 0xFF000000;
box.backgroundColor2 = picker->color | ((uint32_t) (255.0f * picker->opacity) << 24); box.backgroundColor2 = picker->color | ((uint32_t) (255.0f * picker->opacity) << 24);
box.borders = ES_RECT_1(2); box.borderSize = 2;
box.cornerRadiusTopLeft = box.cornerRadiusTopRight = box.cornerRadiusBottomLeft = box.cornerRadiusBottomRight = Width(box.bounds) / 2; box.cornerRadius = Width(box.bounds) / 2;
if (picker->opacity < 1 && picker->host.hasOpacity) { 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. // TODO Move the alpha background as the chosen point moves.
return EsColorBlend(((((x - 2) >> 3) ^ ((y + 5) >> 3)) & 1) ? 0xFFFFFFFF : 0xFFC0C0C0, return EsColorBlend(((((x - 2) >> 3) ^ ((y + 5) >> 3)) & 1) ? 0xFFFFFFFF : 0xFFC0C0C0,
box->backgroundColor2, false); box->backgroundColor2, false);
@ -4553,10 +4600,9 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) {
if (message->type == ES_MSG_PAINT) { if (message->type == ES_MSG_PAINT) {
EsRectangle bounds = EsPainterBoundsInset(message->painter); EsRectangle bounds = EsPainterBoundsInset(message->painter);
EsStyledBox box = {}; StyledBox box = {};
box.bounds = bounds; box.bounds = bounds;
box.clip = message->painter->clip; box.borderSize = 1;
box.borders = ES_RECT_1(1);
if (well->indeterminate) { if (well->indeterminate) {
box.backgroundColor = 0; box.backgroundColor = 0;
@ -4567,7 +4613,7 @@ int ProcessColorWellMessage(EsElement *element, EsMessage *message) {
box.borderColor = EsColorBlend(well->color | 0xFF000000, 0x40000000, false); box.borderColor = EsColorBlend(well->color | 0xFF000000, 0x40000000, false);
if ((well->flags & ES_COLOR_WELL_HAS_OPACITY) && ((well->color & 0xFF000000) != 0xFF000000)) { 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) return EsColorBlend(((((x - box->bounds.l - 4) >> 3) ^ ((y - box->bounds.t + 2) >> 3)) & 1)
? 0xFFFFFFFF : 0xFFC0C0C0, box->backgroundColor, false); ? 0xFFFFFFFF : 0xFFC0C0C0, box->backgroundColor, false);
}; };

View File

@ -67,10 +67,6 @@
#define THEME_CHILD_TYPE_NONE (3) #define THEME_CHILD_TYPE_NONE (3)
#define THEME_CHILD_TYPE_HORIZONTAL (1 << 4) #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 { typedef enum ThemeCursor {
THEME_CURSOR_NORMAL, THEME_CURSOR_NORMAL,
THEME_CURSOR_TEXT, THEME_CURSOR_TEXT,
@ -130,6 +126,10 @@ typedef struct ThemePaintRadialGradient {
// Followed by gradient stops. // Followed by gradient stops.
} ThemePaintRadialGradient; } ThemePaintRadialGradient;
#ifndef IN_DESIGNER
typedef uint32_t (*EsFragmentShaderCallback)(int x, int y, struct StyledBox *box);
#endif
typedef struct ThemePaintCustom { typedef struct ThemePaintCustom {
#ifndef IN_DESIGNER #ifndef IN_DESIGNER
EsFragmentShaderCallback callback; EsFragmentShaderCallback callback;
@ -453,7 +453,7 @@ void ThemeFillRectangle(EsPainter *painter, EsRectangle bounds, ThemePaintData p
uint32_t *b = bits + bounds.l + y * width; uint32_t *b = bits + bounds.l + y * width;
do { 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++; x++, b++;
} while (x < bounds.r); } while (x < bounds.r);
} }
@ -525,7 +525,7 @@ void ThemeFillCorner(EsPainter *painter, EsRectangle bounds, int cx, int cy,
#ifndef IN_DESIGNER #ifndef IN_DESIGNER
} else if (mainPaint.type == THEME_PAINT_CUSTOM) { } else if (mainPaint.type == THEME_PAINT_CUSTOM) {
mainColor = mainPaint.custom->callback((i >> STYLE_CORNER_OVERSAMPLING) - mainGradient->ox + bounds.l, 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 #endif
} else { } else {
mainColor = 0; mainColor = 0;
@ -2186,56 +2186,6 @@ bool UIStyle::IsRegionCompletelyOpaque(EsRectangle region, int width, int height
&& region.t >= opaqueInsets.t && region.b < height - opaqueInsets.b; && 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) { void EsDrawRoundedRectangle(EsPainter *painter, EsRectangle bounds, EsDeviceColor mainColor, EsDeviceColor borderColor, EsRectangle borderSize, const uint32_t *cornerRadii) {
ThemeLayer layer = {}; ThemeLayer layer = {};
uint8_t info[sizeof(ThemeLayerBox) + sizeof(ThemePaintSolid) * 2]; uint8_t info[sizeof(ThemeLayerBox) + sizeof(ThemePaintSolid) * 2];