diff --git a/src/dusk/ui/frame/uiframe.c b/src/dusk/ui/widget/uiframe.c similarity index 100% rename from src/dusk/ui/frame/uiframe.c rename to src/dusk/ui/widget/uiframe.c diff --git a/src/dusk/ui/frame/uiframe.h b/src/dusk/ui/widget/uiframe.h similarity index 100% rename from src/dusk/ui/frame/uiframe.h rename to src/dusk/ui/widget/uiframe.h diff --git a/src/dusk/ui/widget/uilabel.c b/src/dusk/ui/widget/uilabel.c index 347f8d63..4879cc49 100644 --- a/src/dusk/ui/widget/uilabel.c +++ b/src/dusk/ui/widget/uilabel.c @@ -6,25 +6,25 @@ */ #include "uilabel.h" +#include "assert/assert.h" #include "util/memory.h" -#include "util/string.h" #include "display/text/text.h" #include "display/spritebatch/spritebatch.h" #include "display/shader/shaderunlit.h" -void uiLabelInit(uilabel_t *label, const char_t *text) { +void uiLabelInit( + uilabel_t *label, + const char_t *text, + spritebatchsprite_t *sprites, + const int32_t spritesMax +) { + assertNotNull(text, "Text buffer cannot be NULL"); + assertNotNull(sprites, "Sprites buffer cannot be NULL"); + memoryZero(label, sizeof(uilabel_t)); - uiLabelSetText(label, text); -} - -void uiLabelSetText(uilabel_t *label, const char_t *text) { - if(stringCompare(label->text, text) == 0) return; - stringCopy(label->text, text, UI_LABEL_TEXT_MAX); - label->dirty = true; -} - -const char_t * uiLabelGetText(const uilabel_t *label) { - return label->text; + label->text = text; + label->sprites = sprites; + label->spritesMax = spritesMax; } void uiLabelSetX(uilabel_t *label, const float_t x) { @@ -49,6 +49,19 @@ float_t uiLabelGetY(const uilabel_t *label) { void uiLabelRebuffer(uilabel_t *label) { if(!label->dirty) return; + + textMeasure(label->text, &FONT_DEFAULT, &label->width, &label->height); + + int32_t charIndex = 0; + float_t posX = label->x; + float_t posY = label->y; + label->spriteCount = textBuffer( + label->x, label->y, label->text, &FONT_DEFAULT, + label->sprites, label->spritesMax, + &charIndex, &posX, &posY + ); + + label->dirty = false; } errorret_t uiLabelRender(uilabel_t *label, const color_t color) { @@ -62,7 +75,7 @@ errorret_t uiLabelRender(uilabel_t *label, const color_t color) { } }; errorChain(spriteBatchBuffer( - label->buffer, label->spriteCount, &SHADER_UNLIT, material + label->sprites, label->spriteCount, &SHADER_UNLIT, material )); errorOk(); diff --git a/src/dusk/ui/widget/uilabel.h b/src/dusk/ui/widget/uilabel.h index f45923bb..c771a89d 100644 --- a/src/dusk/ui/widget/uilabel.h +++ b/src/dusk/ui/widget/uilabel.h @@ -10,12 +10,10 @@ #include "display/spritebatch/spritebatchsprite.h" #include "display/color.h" -#define UI_LABEL_TEXT_MAX 128 - typedef struct { - char_t text[UI_LABEL_TEXT_MAX]; - spritebatchsprite_t sprites[UI_LABEL_TEXT_MAX]; - spritebatchsprite_t buffer[UI_LABEL_TEXT_MAX]; + const char_t *text; + spritebatchsprite_t *sprites; + int32_t spritesMax; uint32_t spriteCount; int32_t width; int32_t height; @@ -25,28 +23,23 @@ typedef struct { } uilabel_t; /** - * Initializes a label. + * Initializes a label. The caller owns the text buffer and writes its + * contents directly (setting label->dirty afterwards); call + * uiLabelRebuffer or uiLabelRender to rebuild the cached sprites. * * @param label The label to initialize. - * @param text Display text; copied internally, safe to be transient. + * @param text Caller-owned, null-terminated string the label reads from + * directly; never written to by the label. Cannot be NULL. + * @param sprites Caller-owned sprite buffer the label writes cached + * glyph sprites into. Cannot be NULL. + * @param spritesMax Number of sprites the sprites buffer can hold. */ -void uiLabelInit(uilabel_t *label, const char_t *text); - -/** - * Sets the display text of the label, rebuilding its cached sprites. - * - * @param label The label to update. - * @param text Display text; copied internally, safe to be transient. - */ -void uiLabelSetText(uilabel_t *label, const char_t *text); - -/** - * Returns the display text of the label. - * - * @param label The label to query. - * @returns The label's text. - */ -const char_t * uiLabelGetText(const uilabel_t *label); +void uiLabelInit( + uilabel_t *label, + const char_t *text, + spritebatchsprite_t *sprites, + const int32_t spritesMax +); /** * Sets the screen x position of the label. @@ -81,10 +74,9 @@ void uiLabelSetY(uilabel_t *label, const float_t y); float_t uiLabelGetY(const uilabel_t *label); /** - * Rebuffers the label: rebuilds its cached local-space sprites if the - * text has changed, then re-translates them into its render buffer at - * its current x/y position. Called internally by uiLabelRender when - * either dirty flag is set. + * Rebuffers the label's cached sprites from its current text at its + * current x/y position. No-op unless the label is dirty. Called + * internally by uiLabelRender. * * @param label The label to rebuffer. */