diff --git a/src/pc/djui/djui.h b/src/pc/djui/djui.h index 4c30d064..840cc65f 100644 --- a/src/pc/djui/djui.h +++ b/src/pc/djui/djui.h @@ -31,6 +31,7 @@ #include "djui_popup.h" #include "djui_chat_box.h" #include "djui_chat_message.h" +#include "djui_paginated.h" #include "djui_panel.h" #include "djui_panel_menu.h" diff --git a/src/pc/djui/djui_flow_layout.c b/src/pc/djui/djui_flow_layout.c index 4b5660d1..da5111f2 100644 --- a/src/pc/djui/djui_flow_layout.c +++ b/src/pc/djui/djui_flow_layout.c @@ -21,6 +21,7 @@ void djui_flow_layout_set_margin_type(struct DjuiFlowLayout* layout, enum DjuiSc //////////// static void djui_flow_layout_on_child_render(struct DjuiBase* base, struct DjuiBase* child) { + if (!child->visible) { return; } struct DjuiFlowLayout* layout = (struct DjuiFlowLayout*)base; switch (layout->flowDirection) { case DJUI_FLOW_DIR_DOWN: diff --git a/src/pc/djui/djui_paginated.c b/src/pc/djui/djui_paginated.c new file mode 100644 index 00000000..d98ce51d --- /dev/null +++ b/src/pc/djui/djui_paginated.c @@ -0,0 +1,134 @@ +#include "djui.h" + + //////////////// + // properties // +//////////////// + + //////////// + // events // +//////////// + +static void djui_paginated_prev(struct DjuiBase* base) { + struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent; + paginated->startIndex -= paginated->showCount; + if (paginated->startIndex < 0) { paginated->startIndex = 0; } +} + +static void djui_paginated_next(struct DjuiBase* base) { + struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent; + paginated->startIndex += paginated->showCount; + + s32 count = 0; + struct DjuiBaseChild* dbc = paginated->layout->base.child; + while (dbc != NULL) { + count++; + dbc = dbc->next; + } + + if (paginated->startIndex >= count) { paginated->startIndex -= paginated->showCount; } +} + +void djui_paginated_calculate_height(struct DjuiPaginated* paginated) { + struct DjuiBaseChild* dbc = paginated->layout->base.child; + + f32 height = 0; + s32 count = 0; + + while (dbc != NULL) { + struct DjuiBase* cbase = dbc->base; + if (count < paginated->showCount) { + if (height != 0) { + height += paginated->layout->margin.value; + } + height += cbase->height.value; + } + count++; + dbc = dbc->next; + } + + if (count <= paginated->showCount) { + djui_base_set_visible(&paginated->prevButton->base, false); + djui_base_set_visible(&paginated->nextButton->base, false); + } else { + djui_base_set_visible(&paginated->prevButton->base, true); + djui_base_set_visible(&paginated->nextButton->base, true); + height += paginated->layout->margin.value; + height += paginated->nextButton->base.height.value; + } + + djui_base_set_size(&paginated->base, paginated->base.width.value, height); +} + +bool djui_paginated_render(struct DjuiBase* base) { + struct DjuiPaginated* paginated = (struct DjuiPaginated*)base; + struct DjuiBaseChild* dbc = paginated->layout->base.child; + + s32 index = 0; + s32 shown = 0; + + while (dbc != NULL) { + struct DjuiBase* cbase = dbc->base; + if (index < paginated->startIndex || shown >= paginated->showCount) { + djui_base_set_visible(cbase, false); + } else { + djui_base_set_visible(cbase, true); + shown++; + } + index++; + dbc = dbc->next; + } + + djui_rect_render(base); + return true; +} + +static void djui_paginated_destroy(struct DjuiBase* base) { + struct DjuiPaginated* paginated = (struct DjuiPaginated*)base; + free(paginated); +} + +struct DjuiPaginated* djui_paginated_create(struct DjuiBase* parent, u32 showCount) { + struct DjuiPaginated* paginated = calloc(1, sizeof(struct DjuiPaginated)); + paginated->showCount = showCount; + struct DjuiBase* base = &paginated->base; + + float bodyHeight = 416; + + djui_base_init(parent, base, djui_paginated_render, djui_paginated_destroy); + djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(base, 1.0, bodyHeight); + djui_base_set_color(base, 0, 64, 0, 0); + djui_base_set_alignment(base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); + + { + struct DjuiFlowLayout* layout = djui_flow_layout_create(base); + djui_base_set_alignment(&layout->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); + djui_base_set_location(&layout->base, 0, 0); + djui_base_set_size_type(&layout->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&layout->base, 1.0f, bodyHeight); + djui_base_set_color(&layout->base, 0, 0, 0, 0); + djui_flow_layout_set_margin(layout, 16); + djui_flow_layout_set_flow_direction(layout, DJUI_FLOW_DIR_DOWN); + paginated->layout = layout; + } + + { + struct DjuiButton* button = djui_button_create(&paginated->base, "<"); + djui_base_set_alignment(&button->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM); + djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button->base, 128, 32); + djui_interactable_hook_click(&button->base, djui_paginated_prev); + paginated->prevButton = button; + } + + { + struct DjuiButton* button = djui_button_create(&paginated->base, ">"); + djui_base_set_alignment(&button->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); + djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button->base, 128, 32); + djui_interactable_hook_click(&button->base, djui_paginated_next); + paginated->nextButton = button; + } + + return paginated; +} diff --git a/src/pc/djui/djui_paginated.h b/src/pc/djui/djui_paginated.h new file mode 100644 index 00000000..4c36a7ab --- /dev/null +++ b/src/pc/djui/djui_paginated.h @@ -0,0 +1,14 @@ +#pragma once +#include "djui.h" + +struct DjuiPaginated { + struct DjuiBase base; + struct DjuiFlowLayout* layout; + struct DjuiButton* prevButton; + struct DjuiButton* nextButton; + s32 startIndex; + s32 showCount; +}; + +void djui_paginated_calculate_height(struct DjuiPaginated* paginated); +struct DjuiPaginated* djui_paginated_create(struct DjuiBase* parent, u32 showCount); diff --git a/src/pc/djui/djui_panel_dynos.c b/src/pc/djui/djui_panel_dynos.c index 9a70d7b2..86f8cd6a 100644 --- a/src/pc/djui/djui_panel_dynos.c +++ b/src/pc/djui/djui_panel_dynos.c @@ -9,18 +9,20 @@ static void djui_panel_dynos_apply(struct DjuiBase* caller) { void djui_panel_dynos_create(struct DjuiBase* caller) { int packCount = dynos_packs_get_count(); - f32 bodyHeight = 32 * (packCount) + 64 * 1 + 16 * (packCount + 1); + f32 bodyHeight = (416) + 64 * 1 + 16 * 1; struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\D\\#1be700\\Y\\#00b3ff\\N\\#ffef00\\O\\#ff0800\\S"); struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); { + struct DjuiPaginated* paginated = djui_paginated_create(&body->base, 8); + struct DjuiBase* layoutBase = &paginated->layout->base; for (int i = 0; i < packCount; i++) { bool tmp = dynos_packs_get_enabled(i); const char* pack = dynos_packs_get(i); - struct DjuiCheckbox* checkbox1 = djui_checkbox_create(&body->base, pack, &tmp); + struct DjuiCheckbox* checkbox1 = djui_checkbox_create(layoutBase, pack, &tmp); checkbox1->base.tag = i; checkbox1->base.bTag = tmp; checkbox1->value = &checkbox1->base.bTag; @@ -30,12 +32,16 @@ void djui_panel_dynos_create(struct DjuiBase* caller) { djui_interactable_hook_value_change(&checkbox1->base, djui_panel_dynos_apply); if (i == 0) { defaultBase = &checkbox1->base; } } + djui_paginated_calculate_height(paginated); struct DjuiButton* button6 = djui_button_create(&body->base, "Back"); djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button6->base, 1.0f, 64); djui_button_set_style(button6, 1); djui_interactable_hook_click(&button6->base, djui_panel_menu_back); + if (defaultBase == NULL) { defaultBase = &button6->base; } + + panel->bodySize.value = paginated->base.height.value + 16 + 64; } djui_panel_add(caller, &panel->base, defaultBase); diff --git a/src/pc/djui/djui_panel_host_mods.c b/src/pc/djui/djui_panel_host_mods.c index b2257ffb..20f328ee 100644 --- a/src/pc/djui/djui_panel_host_mods.c +++ b/src/pc/djui/djui_panel_host_mods.c @@ -84,7 +84,7 @@ static void djui_panel_host_mods_destroy(struct DjuiBase* base) { } void djui_panel_host_mods_create(struct DjuiBase* caller) { - f32 bodyHeight = 32 * gModTableLocal.entryCount + 64 * 1 + 16 * (gModTableLocal.entryCount + 1); + f32 bodyHeight = (416) + 64 * 1 + 16 * 1; mod_list_update_selectable(); @@ -93,23 +93,26 @@ void djui_panel_host_mods_create(struct DjuiBase* caller) { struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); sModPanelBody = body; { + struct DjuiPaginated* paginated = djui_paginated_create(&body->base, 8); + struct DjuiBase* layoutBase = &paginated->layout->base; for (int i = 0; i < gModTableLocal.entryCount; i++) { struct ModListEntry* entry = &gModTableLocal.entries[i]; - struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, entry->displayName ? entry->displayName : entry->name, &entry->enabled); + struct DjuiCheckbox* checkbox = djui_checkbox_create(layoutBase, entry->displayName ? entry->displayName : entry->name, &entry->enabled); checkbox->base.tag = i; djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&checkbox->base, 1.0f, 32); - djui_base_set_enabled(&checkbox->base, entry->selectable); - djui_interactable_hook_hover(&checkbox->base, djui_mod_checkbox_on_hover, djui_mod_checkbox_on_hover_end); - djui_interactable_hook_value_change(&checkbox->base, djui_mod_checkbox_on_value_change); + if (i == 0) { defaultBase = &checkbox->base; } } + djui_paginated_calculate_height(paginated); struct DjuiButton* button1 = djui_button_create(&body->base, "Back"); djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 1.0f, 64); djui_button_set_style(button1, 1); djui_interactable_hook_click(&button1->base, djui_panel_menu_back); - defaultBase = &button1->base; + if (defaultBase == NULL) { defaultBase = &button1->base; } + + panel->bodySize.value = paginated->base.height.value + 16 + 64; } panel->base.destroy = djui_panel_host_mods_destroy;