From 121d9697957246dcbfb85cc118fa8ecf99b1292c Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 18 Jun 2021 18:53:41 -0700 Subject: [PATCH] DJUI: Added borders to DjuiBase --- src/pc/djui/djui.c | 4 +- src/pc/djui/djui_base.c | 91 +++++++++++++++++++++++++++++++++++++++ src/pc/djui/djui_base.h | 5 +++ src/pc/djui/djui_button.c | 2 + src/pc/djui/djui_text.c | 3 -- 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index 1b6e4810..8d64cb9d 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -72,8 +72,8 @@ void djui_render(void) { 32.0f + cos((sTimer) / 10.0f) * 64.0f, 32.0f + sin((sTimer) / 31.0f) * 64.0f); - djui_base_set_size(&sDjuiButton->base, + /*djui_base_set_size(&sDjuiButton->base, 200.0f + cos((sTimer) / 10.0f) * 64.0f, - 64.0f + sin((sTimer) / 10.0f) * 16.0f); + 64.0f + sin((sTimer) / 10.0f) * 77.0f);*/ } } \ No newline at end of file diff --git a/src/pc/djui/djui_base.c b/src/pc/djui/djui_base.c index bf05bfed..0d30233d 100644 --- a/src/pc/djui/djui_base.c +++ b/src/pc/djui/djui_base.c @@ -32,6 +32,21 @@ void djui_base_set_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a) { base->color.a = a; } +void djui_base_set_border_width(struct DjuiBase* base, f32 width) { + base->borderWidth.value = width; +} + +void djui_base_set_border_width_type(struct DjuiBase* base, enum DjuiScreenValueType widthType) { + base->borderWidth.type = widthType; +} + +void djui_base_set_border_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a) { + base->borderColor.r = r; + base->borderColor.g = g; + base->borderColor.b = b; + base->borderColor.a = a; +} + void djui_base_set_alignment(struct DjuiBase* base, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign) { base->hAlign = hAlign; base->vAlign = vAlign; @@ -127,6 +142,72 @@ static void djui_base_add_child(struct DjuiBase* parent, struct DjuiBase* base) } } + //////////// + // render // +//////////// + +static f32 djui_base_render_border_piece(struct DjuiBase* base, f32 x1, f32 y1, f32 x2, f32 y2, bool isXBorder) { + struct DjuiBaseRect* clip = &base->clip; + + x1 = fmax(x1, clip->x); + y1 = fmax(y1, clip->y); + x2 = fmin(x2, clip->x + clip->width); + y2 = fmin(y2, clip->y + clip->height); + + if (x2 <= x1) { return 0; } + if (y2 <= y1) { return 0; } + + // translate position + f32 translatedX = x1; + f32 translatedY = y1; + djui_gfx_position_translate(&translatedX, &translatedY); + create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, 0); + + // translate size + f32 translatedWidth = x2 - x1; + f32 translatedHeight = y2 - y1; + djui_gfx_scale_translate(&translatedWidth, &translatedHeight); + create_dl_scale_matrix(DJUI_MTX_NOPUSH, translatedWidth, translatedHeight, 1.0f); + + // render + gDPSetEnvColor(gDisplayListHead++, base->borderColor.r, base->borderColor.g, base->borderColor.b, base->borderColor.a); + gSPDisplayList(gDisplayListHead++, dl_djui_simple_rect); + + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + + return isXBorder ? fmax(x2 - x1, 0) : fmax(y2 - y1, 0); +} + +static void djui_base_render_border(struct DjuiBase* base) { + struct DjuiBaseRect* comp = &base->comp; + struct DjuiBaseRect* clip = &base->clip; + struct DjuiBaseRect savedComp = base->comp; + + f32 xBorderWidth = fmin(base->borderWidth.value, savedComp.width / 2.0f); + f32 yBorderWidth = fmin(base->borderWidth.value, savedComp.height / 2.0f); + + comp->x += base->borderWidth.value; + comp->y += base->borderWidth.value; + comp->width -= base->borderWidth.value * 2.0f; + comp->height -= base->borderWidth.value * 2.0f; + + f32 addClip = 0; + + addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y, savedComp.x + savedComp.width, savedComp.y + yBorderWidth, false); + clip->y += addClip; + clip->height -= addClip; + + addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y + savedComp.height - yBorderWidth, savedComp.x + savedComp.width, savedComp.y + savedComp.height, false); + clip->height -= addClip; + + addClip = djui_base_render_border_piece(base, savedComp.x, savedComp.y, savedComp.x + xBorderWidth, savedComp.y + savedComp.height, true); + clip->x += addClip; + clip->width -= addClip; + + addClip = djui_base_render_border_piece(base, savedComp.x + savedComp.width - xBorderWidth, savedComp.y, savedComp.x + savedComp.width, savedComp.y + savedComp.height, true); + clip->width -= addClip; +} + //////////// // events // //////////// @@ -135,9 +216,19 @@ void djui_base_render(struct DjuiBase* base) { if (!base->visible) { return; } struct DjuiBaseRect* comp = &base->comp; + struct DjuiBaseRect* clip = &base->clip; + djui_base_compute(base); if (comp->width <= 0) { return; } if (comp->height <= 0) { return; } + if (clip->width <= 0) { return; } + if (clip->height <= 0) { return; } + + if (base->borderWidth.value > 0 && base->borderColor.a > 0) { + djui_base_render_border(base); + } + + if (clip->width < 0 || clip->height <= 0) { return; } if (base->render != NULL) { base->render(base); diff --git a/src/pc/djui/djui_base.h b/src/pc/djui/djui_base.h index 3624002e..7f59f8d8 100644 --- a/src/pc/djui/djui_base.h +++ b/src/pc/djui/djui_base.h @@ -25,6 +25,8 @@ struct DjuiBase { struct DjuiScreenValue width; struct DjuiScreenValue height; struct DjuiColor color; + struct DjuiScreenValue borderWidth; + struct DjuiColor borderColor; enum DjuiHAlign hAlign; enum DjuiVAlign vAlign; struct DjuiBaseRect comp; @@ -38,6 +40,9 @@ void djui_base_set_location_type(struct DjuiBase* base, enum DjuiScreenValueType void djui_base_set_size(struct DjuiBase* base, f32 width, f32 height); void djui_base_set_size_type(struct DjuiBase* base, f32 widthType, f32 heightType); void djui_base_set_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a); +void djui_base_set_border_width(struct DjuiBase* base, f32 width); +void djui_base_set_border_width_type(struct DjuiBase* base, enum DjuiScreenValueType widthType); +void djui_base_set_border_color(struct DjuiBase* base, u8 r, u8 g, u8 b, u8 a); void djui_base_set_alignment(struct DjuiBase* base, enum DjuiHAlign hAlign, enum DjuiVAlign vAlign); void djui_base_compute(struct DjuiBase* base); diff --git a/src/pc/djui/djui_button.c b/src/pc/djui/djui_button.c index a75ba5c0..3ee5fa64 100644 --- a/src/pc/djui/djui_button.c +++ b/src/pc/djui/djui_button.c @@ -11,6 +11,8 @@ struct DjuiButton* djui_button_create(struct DjuiBase* parent, const char* messa djui_base_init(parent, base, NULL, djui_button_destroy); djui_base_set_size(base, 200, 64); + djui_base_set_border_width(base, 2); + djui_base_set_border_color(base, 173, 173, 173, 255); struct DjuiRect* rect = djui_rect_create(&button->base); djui_base_set_size_type(&rect->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); diff --git a/src/pc/djui/djui_text.c b/src/pc/djui/djui_text.c index 5fff8131..8dc555df 100644 --- a/src/pc/djui/djui_text.c +++ b/src/pc/djui/djui_text.c @@ -190,9 +190,6 @@ static void djui_text_render(struct DjuiBase* base) { sTextRenderLastX = 0; sTextRenderLastY = 0; - // compute base - djui_base_compute(base); - // translate position f32 translatedX = comp->x; f32 translatedY = comp->y;