DJUI: Added interactable mousedown events

This commit is contained in:
MysterD 2021-06-19 19:50:59 -07:00
parent 6e23c952f9
commit 5e6eb8e833
5 changed files with 135 additions and 53 deletions

View file

@ -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
}

View file

@ -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);

View file

@ -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;
}

View file

@ -1,31 +1,103 @@
#include <string.h>
#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;
}

View file

@ -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*));