Added quit menu

create enabled switch to disable interactables
fixed djui_base_destroy()
added on_click() event
This commit is contained in:
MysterD 2021-06-21 02:35:42 -07:00
parent c0b093b11f
commit 7aec232450
14 changed files with 219 additions and 37 deletions

View file

@ -3948,6 +3948,8 @@
<ClCompile Include="..\src\pc\djui\djui_gfx.c" />
<ClCompile Include="..\src\pc\djui\djui_image.c" />
<ClCompile Include="..\src\pc\djui\djui_interactable.c" />
<ClCompile Include="..\src\pc\djui\djui_panel_main.c" />
<ClCompile Include="..\src\pc\djui\djui_panel_quit.c" />
<ClCompile Include="..\src\pc\djui\djui_rect.c" />
<ClCompile Include="..\src\pc\djui\djui_root.c" />
<ClCompile Include="..\src\pc\djui\djui_text.c" />
@ -4017,6 +4019,7 @@
<ClCompile Include="..\src\pc\pc_main.c" />
<ClCompile Include="..\src\pc\platform.c" />
<ClCompile Include="..\src\pc\ultra_reimplementation.c" />
<ClCompile Include="..\src\pc\utils\misc.c" />
<ClCompile Include="..\src\pc\utils\string_linked_list.c" />
<ClCompile Include="..\text\define_courses.inc.c" />
<ClCompile Include="..\text\define_text.inc.c" />
@ -4370,6 +4373,8 @@
<ClInclude Include="..\src\pc\djui\djui_gfx.h" />
<ClInclude Include="..\src\pc\djui\djui_image.h" />
<ClInclude Include="..\src\pc\djui\djui_interactable.h" />
<ClInclude Include="..\src\pc\djui\djui_panel_main.h" />
<ClInclude Include="..\src\pc\djui\djui_panel_quit.h" />
<ClInclude Include="..\src\pc\djui\djui_rect.h" />
<ClInclude Include="..\src\pc\djui\djui_root.h" />
<ClInclude Include="..\src\pc\djui\djui_text.h" />
@ -4388,6 +4393,7 @@
<ClInclude Include="..\src\pc\network\socket\socket_linux.h" />
<ClInclude Include="..\src\pc\network\socket\socket_windows.h" />
<ClInclude Include="..\src\pc\network\version.h" />
<ClInclude Include="..\src\pc\utils\misc.h" />
<ClInclude Include="..\src\pc\utils\string_linked_list.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View file

@ -15189,6 +15189,15 @@
<ClCompile Include="..\src\pc\djui\djui_button.c">
<Filter>Source Files\src\pc\djui\component\compound</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\djui\djui_panel_main.c">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\djui\djui_panel_quit.c">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\utils\misc.c">
<Filter>Source Files\src\pc\utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\actors\common0.h">
@ -16198,5 +16207,14 @@
<ClInclude Include="..\src\pc\djui\djui_button.h">
<Filter>Source Files\src\pc\djui\component\compound</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\djui\djui_panel_main.h">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\djui\djui_panel_quit.h">
<Filter>Source Files\src\pc\djui\panel</Filter>
</ClInclude>
<ClInclude Include="..\src\pc\utils\misc.h">
<Filter>Source Files\src\pc\utils</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -21,6 +21,7 @@
#include "djui_flow_layout.h"
#include "djui_panel_main.h"
#include "djui_panel_quit.h"
extern struct DjuiRoot* gDjuiRoot;

View file

@ -9,6 +9,10 @@ void djui_base_set_visible(struct DjuiBase* base, bool visible) {
base->visible = visible;
}
void djui_base_set_enabled(struct DjuiBase* base, bool enabled) {
base->enabled = enabled;
}
void djui_base_set_location(struct DjuiBase* base, f32 x, f32 y) {
base->x.value = x;
base->y.value = y;
@ -150,7 +154,8 @@ void djui_base_compute(struct DjuiBase* base) {
comp->width = width;
comp->height = height;
//djui_base_add_padding(base);
base->elem = base->comp;
djui_base_clip(base);
}
@ -256,7 +261,9 @@ void djui_base_render(struct DjuiBase* base) {
if (!base->visible) { return; }
if (base->on_render_pre != NULL) {
base->on_render_pre(base);
bool skipRender = false;
base->on_render_pre(base, &skipRender);
if (skipRender) { return; }
}
struct DjuiBaseRect* comp = &base->comp;
@ -283,13 +290,14 @@ void djui_base_render(struct DjuiBase* base) {
// render all children
struct DjuiBaseChild* child = base->child;
while (child != NULL) {
struct DjuiBaseChild* nextChild = child->next;
djui_base_render(child->base);
if (base->on_child_render != NULL) {
base->on_child_render(base, child->base);
}
child = child->next;
child = nextChild;
}
}
@ -298,13 +306,16 @@ void djui_base_destroy(struct DjuiBase* base) {
if (base->parent != NULL) {
struct DjuiBaseChild* child = base->parent->child;
struct DjuiBaseChild* lastChild = NULL;
struct DjuiBaseChild* nextChild = NULL;
while (child != NULL) {
nextChild = child->next;
if (child->base == base) {
// adjust linked list
if (lastChild == NULL) {
base->parent->child = child->next;
base->parent->child = nextChild;
} else {
lastChild->next = child->next;
lastChild->next = nextChild;
}
// deallocate child node
free(child);
@ -314,18 +325,18 @@ void djui_base_destroy(struct DjuiBase* base) {
// iterate
lastChild = child;
child = child->next;
child = nextChild;
}
}
// destroy all children and our linked list
struct DjuiBaseChild* child = base->child;
while (child != NULL) {
struct DjuiBaseChild* nextChild = child;
struct DjuiBaseChild* nextChild = child->next;
child->base->parent = NULL;
djui_base_destroy(child->base);
free(child);
child = nextChild->next;
child = nextChild;
}
// deallocate interactable
@ -341,7 +352,8 @@ void djui_base_destroy(struct DjuiBase* base) {
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, void(*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*)) {
memset(base, 0, sizeof(struct DjuiBase));
base->parent = parent;
base->visible = true;
djui_base_set_visible(base, true);
djui_base_set_enabled(base, true);
djui_base_set_size(base, 64, 64);
djui_base_set_color(base, 255, 255, 255, 255);
base->render = render;

View file

@ -28,6 +28,7 @@ struct DjuiBase {
struct DjuiBase* parent;
struct DjuiBaseChild* child;
bool visible;
bool enabled;
struct DjuiScreenValue x;
struct DjuiScreenValue y;
struct DjuiScreenValue width;
@ -38,16 +39,18 @@ struct DjuiBase {
struct DjuiBasePadding padding;
enum DjuiHAlign hAlign;
enum DjuiVAlign vAlign;
struct DjuiBaseRect elem;
struct DjuiBaseRect comp;
struct DjuiBaseRect clip;
struct DjuiInteractable* interactable;
void (*on_child_render)(struct DjuiBase*, struct DjuiBase*);
void (*on_render_pre)(struct DjuiBase*);
void (*on_render_pre)(struct DjuiBase*, bool*);
void (*render)(struct DjuiBase*);
void (*destroy)(struct DjuiBase*);
};
void djui_base_set_visible(struct DjuiBase* base, bool visible);
void djui_base_set_enabled(struct DjuiBase* base, bool enabled);
void djui_base_set_location(struct DjuiBase* base, f32 x, f32 y);
void djui_base_set_location_type(struct DjuiBase* base, enum DjuiScreenValueType xType, enum DjuiScreenValueType yType);
void djui_base_set_size(struct DjuiBase* base, f32 width, f32 height);

View file

@ -25,18 +25,18 @@ static void djui_flow_layout_on_child_render(struct DjuiBase* base, struct DjuiB
struct DjuiFlowLayout* layout = (struct DjuiFlowLayout*)base;
switch (layout->flowDirection) {
case DJUI_FLOW_DIR_DOWN:
base->comp.y += (child->comp.height + layout->margin.value);
base->comp.height -= (child->comp.height + layout->margin.value);
base->comp.y += (child->elem.height + layout->margin.value);
base->comp.height -= (child->elem.height + layout->margin.value);
break;
case DJUI_FLOW_DIR_UP:
base->comp.height -= (child->comp.height + layout->margin.value);
base->comp.height -= (child->elem.height + layout->margin.value);
break;
case DJUI_FLOW_DIR_RIGHT:
base->comp.x += (child->comp.width + layout->margin.value);
base->comp.width -= (child->comp.width + layout->margin.value);
base->comp.x += (child->elem.width + layout->margin.value);
base->comp.width -= (child->elem.width + layout->margin.value);
break;
case DJUI_FLOW_DIR_LEFT:
base->comp.width -= (child->comp.width + layout->margin.value);
base->comp.width -= (child->elem.width + layout->margin.value);
break;
}
}

View file

@ -7,6 +7,22 @@
struct DjuiBase* sHovered = NULL;
struct DjuiBase* sMouseDown = NULL;
static bool djui_interactable_mouse_inside(struct DjuiBase* base) {
struct DjuiBaseRect* clip = &base->elem;
if (mouse_window_x < clip->x) { return false; }
if (mouse_window_x > clip->x + clip->width) { return false; }
if (mouse_window_y < clip->y) { return false; }
if (mouse_window_y > clip->y + clip->height) { return false; }
return true;
}
static void djui_interactable_on_click(struct DjuiBase* base) {
if (base == NULL) { return; }
if (base->interactable == NULL) { return; }
if (base->interactable->on_click == NULL) { return; }
base->interactable->on_click(base);
}
static void djui_interactable_on_hover_begin(struct DjuiBase* base) {
if (base == NULL) { return; }
if (base->interactable == NULL) { return; }
@ -39,18 +55,26 @@ static void djui_interactable_on_mouse_down_end(struct DjuiBase* base) {
if (base->interactable == NULL) { return; }
if (base->interactable->on_mouse_down_end == NULL) { return; }
base->interactable->on_mouse_down_end(base);
if (djui_interactable_mouse_inside(base)) {
djui_interactable_on_click(base);
}
}
static void djui_interactable_mouse_update_active(struct DjuiBase* base) {
if (!base->visible) { return; }
if (!base->enabled) { 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; }
static struct DjuiBase* insideParent = NULL;
if (base->interactable != NULL) { sHovered = base; }
if (!djui_interactable_mouse_inside(base)) { return; }
if (base->interactable != NULL) {
sHovered = base;
insideParent = base;
} else if (insideParent == NULL) {
sHovered = NULL;
}
// check all children
struct DjuiBaseChild* child = base->child;
@ -58,6 +82,10 @@ static void djui_interactable_mouse_update_active(struct DjuiBase* base) {
djui_interactable_mouse_update_active(child->base);
child = child->next;
}
if (insideParent == base) {
insideParent = NULL;
}
}
void djui_interactable_update(void) {
@ -98,6 +126,7 @@ void djui_interactable_create(struct DjuiBase* base,
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;
interactable->on_click = NULL;
base->interactable = interactable;
}

View file

@ -4,10 +4,12 @@
#pragma pack(1)
struct DjuiInteractable {
bool enabled;
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 (*on_click)(struct DjuiBase*);
};
void djui_interactable_update(void);

View file

@ -4,28 +4,29 @@ ALIGNED8 static u8 texture_title[] = {
#include "textures/segment2/custom_title.rgba32.inc.c"
};
struct DjuiRect* gPanelMainMenu = NULL;
struct DjuiRect* sTitleContainer = NULL;
struct DjuiFlowLayout* sButtonContainer = NULL;
struct DjuiText* sVersionText = NULL;
static void djui_panel_main_render_pre(struct DjuiBase* base) {
sTitleContainer->base.height.value = sButtonContainer->base.clip.y - sTitleContainer->base.clip.y;
static void djui_panel_main_render_pre(struct DjuiBase* base, bool* skipRender) {
sTitleContainer->base.height.value = sButtonContainer->base.clip.y - gPanelMainMenu->base.comp.y;
sVersionText->base.height.value = sTitleContainer->base.height.value;
}
void djui_panel_main_create(void) {
struct DjuiRect* menuContainer = djui_rect_create(&gDjuiRoot->base);
djui_base_set_size_type(&menuContainer->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
djui_base_set_size(&menuContainer->base, 512.0f + (16 * 2.0f), 1.0f);
djui_base_set_color(&menuContainer->base, 0, 0, 0, 230);
djui_base_set_border_color(&menuContainer->base, 0, 0, 0, 200);
djui_base_set_border_width(&menuContainer->base, 8);
djui_base_set_padding(&menuContainer->base, 16, 16, 16, 16);
gPanelMainMenu = djui_rect_create(&gDjuiRoot->base);
djui_base_set_size_type(&gPanelMainMenu->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
djui_base_set_size(&gPanelMainMenu->base, 512.0f + (16 * 2.0f), 1.0f);
djui_base_set_color(&gPanelMainMenu->base, 0, 0, 0, 230);
djui_base_set_border_color(&gPanelMainMenu->base, 0, 0, 0, 200);
djui_base_set_border_width(&gPanelMainMenu->base, 8);
djui_base_set_padding(&gPanelMainMenu->base, 16, 16, 16, 16);
{
sButtonContainer = djui_flow_layout_create(&menuContainer->base);
sButtonContainer = djui_flow_layout_create(&gPanelMainMenu->base);
djui_base_set_alignment(&sButtonContainer->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
djui_base_set_size_type(&sButtonContainer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&sButtonContainer->base, 1.0f, 292);
djui_base_set_size(&sButtonContainer->base, 1.0f, 64 * 4 + 16 * 3);
djui_base_set_color(&sButtonContainer->base, 0, 0, 0, 0);
djui_flow_layout_set_margin(sButtonContainer, 16);
djui_flow_layout_set_flow_direction(sButtonContainer, DJUI_FLOW_DIR_DOWN);
@ -45,9 +46,11 @@ void djui_panel_main_create(void) {
struct DjuiButton* button4 = djui_button_create(&sButtonContainer->base, "Quit");
djui_base_set_size_type(&button4->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button4->base, 1.0f, 64);
button4->base.interactable->on_click = djui_panel_quit_open;
}
sTitleContainer = djui_rect_create(&menuContainer->base);
sTitleContainer = djui_rect_create(&gPanelMainMenu->base);
djui_base_set_alignment(&sTitleContainer->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
djui_base_set_size_type(&sTitleContainer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&sTitleContainer->base, 1.0f, 1.0f);
djui_base_set_color(&sTitleContainer->base, 0, 0, 0, 0);
@ -59,12 +62,11 @@ void djui_panel_main_create(void) {
djui_base_set_alignment(&title->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
}
sVersionText = djui_text_create(&menuContainer->base, "version - unst 5");
djui_base_set_alignment(&sVersionText->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
sVersionText = djui_text_create(&gPanelMainMenu->base, "version - unst 5");
djui_base_set_alignment(&sVersionText->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
djui_base_set_size_type(&sVersionText->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&sVersionText->base, 1.0f, 1.0f);
djui_base_set_color(&sVersionText->base, 50, 50, 50, 255);
djui_text_set_alignment(sVersionText, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
}
}

View file

@ -1,4 +1,6 @@
#pragma once
#include "djui.h"
extern struct DjuiRect* gPanelMainMenu;
void djui_panel_main_create(void);

View file

@ -0,0 +1,89 @@
#include "djui.h"
#include "src/pc/utils/misc.h"
struct DjuiRect* sPanelQuit = NULL;
bool sOpening = false;
bool sClosing = false;
static void djui_panel_quit_render_pre(struct DjuiBase* base, bool* skipRender) {
float yMove = gPanelMainMenu->base.elem.height;
static float movement = 0;
if (sOpening) {
movement += yMove / 10.0f;
if (movement >= yMove) {
movement = yMove;
sOpening = false;
djui_base_set_enabled(&sPanelQuit->base, true);
}
} else if (sClosing) {
movement -= yMove / 10.0f;
if (movement <= 0) {
movement = 0;
sClosing = false;
djui_base_destroy(&sPanelQuit->base);
sPanelQuit = NULL;
*skipRender = true;
djui_base_set_enabled(&gPanelMainMenu->base, true);
gPanelMainMenu->base.y.value = 0;
return;
}
} else {
movement = yMove;
}
gPanelMainMenu->base.y.value = -yMove * smoothstep(0, yMove, movement);
sPanelQuit->base.y.value = gPanelMainMenu->base.elem.y + gPanelMainMenu->base.elem.height;
}
static void djui_panel_quit_yes(struct DjuiBase* base) {
exit(0);
}
static void djui_panel_quit_no(struct DjuiBase* base) {
sClosing = true;
djui_base_set_enabled(&sPanelQuit->base, false);
}
static void djui_panel_quit_create(void) {
sOpening = true;
sClosing = false;
sPanelQuit = djui_rect_create(&gDjuiRoot->base);
djui_base_set_size_type(&sPanelQuit->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
djui_base_set_size(&sPanelQuit->base, 512.0f + (16 * 2.0f), 1.0f);
djui_base_set_color(&sPanelQuit->base, 0, 0, 0, 230);
djui_base_set_border_color(&sPanelQuit->base, 0, 0, 0, 200);
djui_base_set_border_width(&sPanelQuit->base, 8);
djui_base_set_padding(&sPanelQuit->base, 16, 16, 16, 16);
djui_base_set_enabled(&sPanelQuit->base, false);
sPanelQuit->base.on_render_pre = djui_panel_quit_render_pre;
{
struct DjuiFlowLayout* quitContainer = djui_flow_layout_create(&sPanelQuit->base);
djui_base_set_alignment(&quitContainer->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
djui_base_set_size_type(&quitContainer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&quitContainer->base, 1.0f, 64 * 3 + 16 * 2);
djui_base_set_color(&quitContainer->base, 0, 0, 0, 0);
djui_flow_layout_set_margin(quitContainer, 16);
djui_flow_layout_set_flow_direction(quitContainer, DJUI_FLOW_DIR_DOWN);
{
struct DjuiText* text = djui_text_create(&quitContainer->base, "Are you sure you want to quit?");
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&text->base, 1.0f, 64);
djui_base_set_color(&text->base, 200, 200, 200, 255);
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
struct DjuiButton* button1 = djui_button_create(&quitContainer->base, "Yes");
djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button1->base, 1.0f, 64);
button1->base.interactable->on_click = djui_panel_quit_yes;
struct DjuiButton* button2 = djui_button_create(&quitContainer->base, "No");
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button2->base, 1.0f, 64);
button2->base.interactable->on_click = djui_panel_quit_no;
}
}
}
void djui_panel_quit_open(struct DjuiBase* caller) {
djui_base_set_enabled(&gPanelMainMenu->base, false);
djui_panel_quit_create();
}

View file

@ -0,0 +1,4 @@
#pragma once
#include "djui.h"
void djui_panel_quit_open(struct DjuiBase* caller);

8
src/pc/utils/misc.c Normal file
View file

@ -0,0 +1,8 @@
#include "misc.h"
float smoothstep(float edge0, float edge1, float x) {
float t = (x - edge0) / (edge1 - edge0);
if (t < 0) { t = 0; }
if (t > 1) { t = 1; }
return t * t * (3.0 - 2.0 * t);
}

6
src/pc/utils/misc.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef UTILS_MISC_H
#define UTILS_MISC_H
float smoothstep(float edge0, float edge1, float x);
#endif