diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index bd3272f8a..e13d180b5 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -16,10 +16,13 @@ ALIGNED8 u8 texture_hand_open[] = { #include "textures/intro_raw/hand_open.rgba16.inc.c" }; +ALIGNED8 u8 texture_hand_closed[] = { +#include "textures/intro_raw/hand_closed.rgba16.inc.c" +}; + static Gfx* sSavedDisplayListHead = NULL; struct DjuiRoot* gDjuiRoot = NULL; -struct DjuiBase* gDjuiBaseHovered = NULL; static struct DjuiImage* sMouseCursor = NULL; // v REMOVE ME v @@ -27,7 +30,6 @@ static struct DjuiRect* sDjuiRect = NULL; static struct DjuiRect* sDjuiRect2 = NULL; static struct DjuiText* sDjuiText = NULL; static struct DjuiImage* sDjuiImage = NULL; -static struct DjuiButton* sDjuiButton = NULL; // ^ REMOVE ME ^ static void djui_init(void) { @@ -70,9 +72,22 @@ static void djui_init(void) { djui_text_set_font_size(sDjuiText, 2); djui_text_set_alignment(sDjuiText, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); - sDjuiButton = djui_button_create(&gDjuiRoot->base, "button"); - djui_base_set_alignment(&sDjuiButton->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); - djui_base_set_location(&sDjuiButton->base, 64, 64); + struct DjuiRect* buttonContainer = djui_rect_create(&gDjuiRoot->base); + djui_base_set_alignment(&buttonContainer->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); + djui_base_set_location(&buttonContainer->base, 64, 64); + djui_base_set_size(&buttonContainer->base, 200 + 16, (64 + 16) * 2.0f + 16); + djui_base_set_color(&buttonContainer->base, 0, 0, 0, 64); + djui_base_set_padding(&buttonContainer->base, 16, 16, 16, 16); + + struct DjuiButton* button1 = djui_button_create(&buttonContainer->base, "one"); + djui_base_set_location(&button1->base, 0, 0); + djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button1->base, 1.0f, 64); + + struct DjuiButton* button2 = djui_button_create(&buttonContainer->base, "two"); + djui_base_set_location(&button2->base, 0, 64 + 16); + djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button2->base, 1.0f, 64); } static void djui_debug_update(void) { @@ -91,49 +106,21 @@ static void djui_debug_update(void) { djui_base_set_location(&sDjuiRect2->base, 32.0f + cos((sTimer) / 10.0f) * 64.0f, 32.0f + sin((sTimer) / 31.0f) * 64.0f); - - /*djui_base_set_size(&sDjuiButton->base, - 200.0f + cos((sTimer) / 10.0f) * 64.0f, - 64.0f + sin((sTimer) / 10.0f) * 77.0f);*/ - //sDjuiButton->base.visible = (sTimer % 10) < 5; -} - -static void djui_mouse_update_active(struct DjuiBase* base) { - if (!base->visible) { return; } - - struct DjuiBaseRect* clip = &base->clip; - if (mouse_window_x < clip->x) { return; } - if (mouse_window_x > clip->x + clip->width) { return; } - if (mouse_window_y < clip->y) { return; } - if (mouse_window_y > clip->y + clip->height) { return; } - - if (base->interactable != NULL) { gDjuiBaseHovered = base; } - - // check all children - struct DjuiBaseChild* child = base->child; - while (child != NULL) { - djui_mouse_update_active(child->base); - child = child->next; - } } static void djui_mouse_update(void) { #if defined(CAPI_SDL2) || defined(CAPI_SDL1) controller_sdl_read_mouse_window(); - struct DjuiBase* lastHovered = gDjuiBaseHovered; - gDjuiBaseHovered = NULL; - djui_mouse_update_active(&gDjuiRoot->base); - if (lastHovered != gDjuiBaseHovered) { - djui_interactable_on_hover_end(lastHovered); - } - djui_interactable_on_hover_begin(gDjuiBaseHovered); + djui_interactable_update(); + // adjust mouse cursor djui_base_set_location(&sMouseCursor->base, mouse_window_x - 13, mouse_window_y - 13); - if (gDjuiBaseHovered) { - djui_base_set_color(&sMouseCursor->base, 255, 255, 255, 255); + + if (mouse_window_buttons & 0b0001) { + djui_image_set_image(sMouseCursor, texture_hand_closed, 32, 32); } else { - djui_base_set_color(&sMouseCursor->base, 233, 233, 255, 255); + djui_image_set_image(sMouseCursor, texture_hand_open, 32, 32); } #endif } diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h index 3a270fa28..75ee0808c 100644 --- a/src/pc/djui/djui.h +++ b/src/pc/djui/djui.h @@ -21,7 +21,6 @@ #include "game/ingame_menu.h" extern struct DjuiRoot* gDjuiRoot; -extern struct DjuiBase* gDjuiBaseHovered; void djui_render_patch(void); void djui_render(void); diff --git a/src/pc/djui/djui_button.c b/src/pc/djui/djui_button.c index 51fe5192d..69326bf5e 100644 --- a/src/pc/djui/djui_button.c +++ b/src/pc/djui/djui_button.c @@ -1,15 +1,32 @@ #include "djui.h" +static void djui_button_set_default_style(struct DjuiBase* base) { + struct DjuiButton* button = (struct DjuiButton*)base; + djui_base_set_border_color(base, 173, 173, 173, 255); + djui_base_set_color(&button->rect->base, 200, 200, 200, 255); + djui_base_set_location(&button->text->base, 0.0f, 0.0f); +} + static void djui_button_on_hover_begin(struct DjuiBase* base) { struct DjuiButton* button = (struct DjuiButton*)base; djui_base_set_border_color(base, 0, 120, 215, 255); djui_base_set_color(&button->rect->base, 229, 241, 251, 255); + djui_base_set_location(&button->text->base, -0.5f, -0.5f); } static void djui_button_on_hover_end(struct DjuiBase* base) { + djui_button_set_default_style(base); +} + +static void djui_button_on_mouse_down_begin(struct DjuiBase* base) { struct DjuiButton* button = (struct DjuiButton*)base; - djui_base_set_border_color(base, 173, 173, 173, 255); - djui_base_set_color(&button->rect->base, 200, 200, 200, 255); + djui_base_set_border_color(base, 0, 84, 153, 255); + djui_base_set_color(&button->rect->base, 204, 228, 247, 255); + djui_base_set_location(&button->text->base, 0.5f, 0.5f); +} + +static void djui_button_on_mouse_down_end(struct DjuiBase* base) { + djui_button_set_default_style(base); } static void djui_button_destroy(struct DjuiBase* base) { @@ -24,13 +41,15 @@ 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); - djui_interactable_create(base, djui_button_on_hover_begin, djui_button_on_hover_end); + djui_interactable_create(base, + djui_button_on_hover_begin, + djui_button_on_hover_end, + djui_button_on_mouse_down_begin, + djui_button_on_mouse_down_end); struct DjuiRect* rect = djui_rect_create(&button->base); djui_base_set_size_type(&rect->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); djui_base_set_size(&rect->base, 1.0f, 1.0f); - djui_base_set_color(&rect->base, 200, 200, 200, 255); button->rect = rect; struct DjuiText* text = djui_text_create(&rect->base, message); @@ -41,5 +60,7 @@ struct DjuiButton* djui_button_create(struct DjuiBase* parent, const char* messa djui_text_set_drop_shadow(text, 0, 0, 0, 64); button->text = text; + djui_button_set_default_style(base); + return button; } diff --git a/src/pc/djui/djui_interactable.c b/src/pc/djui/djui_interactable.c index b285c9dc9..54a28b30d 100644 --- a/src/pc/djui/djui_interactable.c +++ b/src/pc/djui/djui_interactable.c @@ -1,31 +1,103 @@ #include #include "djui.h" -void djui_interactable_on_hover_begin(struct DjuiBase* base) { +#include "src/pc/controller/controller_sdl.h" +#include "src/pc/controller/controller_mouse.h" + +struct DjuiBase* sHovered = NULL; +struct DjuiBase* sMouseDown = NULL; + +static void djui_interactable_on_hover_begin(struct DjuiBase* base) { if (base == NULL) { return; } if (base->interactable == NULL) { return; } if (base->interactable->on_hover_begin == NULL) { return; } base->interactable->on_hover_begin(base); } -void djui_interactable_on_hover_end(struct DjuiBase* base) { +static void djui_interactable_on_hover_end(struct DjuiBase* base) { if (base == NULL) { return; } if (base->interactable == NULL) { return; } if (base->interactable->on_hover_begin == NULL) { return; } base->interactable->on_hover_end(base); } +static void djui_interactable_on_mouse_down_begin(struct DjuiBase* base) { + if (base == NULL) { return; } + if (base->interactable == NULL) { return; } + if (base->interactable->on_mouse_down_begin == NULL) { return; } + + if (sHovered != NULL) { + djui_interactable_on_hover_end(sHovered); + sHovered = NULL; + } + + base->interactable->on_mouse_down_begin(base); +} + +static void djui_interactable_on_mouse_down_end(struct DjuiBase* base) { + if (base == NULL) { return; } + if (base->interactable == NULL) { return; } + if (base->interactable->on_mouse_down_end == NULL) { return; } + base->interactable->on_mouse_down_end(base); +} + +static void djui_interactable_mouse_update_active(struct DjuiBase* base) { + if (!base->visible) { return; } + + struct DjuiBaseRect* clip = &base->clip; + if (mouse_window_x < clip->x) { return; } + if (mouse_window_x > clip->x + clip->width) { return; } + if (mouse_window_y < clip->y) { return; } + if (mouse_window_y > clip->y + clip->height) { return; } + + if (base->interactable != NULL) { sHovered = base; } + + // check all children + struct DjuiBaseChild* child = base->child; + while (child != NULL) { + djui_interactable_mouse_update_active(child->base); + child = child->next; + } +} + +void djui_interactable_update(void) { + if (mouse_window_buttons & 0b0001) { + if (sHovered != NULL) { + sMouseDown = sHovered; + sHovered = NULL; + djui_interactable_on_mouse_down_begin(sMouseDown); + } + } else { + if (sMouseDown != NULL) { + djui_interactable_on_mouse_down_end(sMouseDown); + sMouseDown = NULL; + } + struct DjuiBase* lastHovered = sHovered; + sHovered = NULL; + djui_interactable_mouse_update_active(&gDjuiRoot->base); + if (lastHovered != sHovered) { + djui_interactable_on_hover_end(lastHovered); + } + djui_interactable_on_hover_begin(sHovered); + } + +} + void djui_interactable_create(struct DjuiBase* base, void (*on_hover_begin)(struct DjuiBase*), - void (*on_hover_end)(struct DjuiBase*)) { + void (*on_hover_end)(struct DjuiBase*), + void (*on_mouse_down_begin)(struct DjuiBase*), + void (*on_mouse_down_end)(struct DjuiBase*)) { if (base->interactable != NULL) { free(base->interactable); } struct DjuiInteractable* interactable = malloc(sizeof(struct DjuiInteractable)); - interactable->on_hover_begin = on_hover_begin; - interactable->on_hover_end = on_hover_end; + interactable->on_hover_begin = on_hover_begin; + interactable->on_hover_end = on_hover_end; + interactable->on_mouse_down_begin = on_mouse_down_begin; + interactable->on_mouse_down_end = on_mouse_down_end; base->interactable = interactable; } \ No newline at end of file diff --git a/src/pc/djui/djui_interactable.h b/src/pc/djui/djui_interactable.h index 057844f28..0b2b805e1 100644 --- a/src/pc/djui/djui_interactable.h +++ b/src/pc/djui/djui_interactable.h @@ -6,11 +6,14 @@ struct DjuiInteractable { void (*on_hover_begin)(struct DjuiBase*); void (*on_hover_end)(struct DjuiBase*); + void (*on_mouse_down_begin)(struct DjuiBase*); + void (*on_mouse_down_end)(struct DjuiBase*); }; -void djui_interactable_on_hover_begin(struct DjuiBase* base); -void djui_interactable_on_hover_end(struct DjuiBase* base); +void djui_interactable_update(void); void djui_interactable_create(struct DjuiBase* base, void (*on_hover_begin)(struct DjuiBase*), - void (*on_hover_end)(struct DjuiBase*)); + void (*on_hover_end)(struct DjuiBase*), + void (*on_mouse_down_begin)(struct DjuiBase*), + void (*on_mouse_down_end)(struct DjuiBase*));