Collapsing more ui settings code

This commit is contained in:
2026-07-07 14:36:19 -05:00
parent fae191d8fe
commit 38c5080f9f
18 changed files with 194 additions and 490 deletions
+4
View File
@@ -29,6 +29,10 @@ msgstr "Audio"
msgid "ui.settings.input.deadzone" msgid "ui.settings.input.deadzone"
msgstr "Deadzone" msgstr "Deadzone"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.apply"
msgstr "Apply"
#: src/dusk/ui/frame/uiconfirm.c #: src/dusk/ui/frame/uiconfirm.c
msgid "ui.confirm.discard_changes" msgid "ui.confirm.discard_changes"
msgstr "Discard unsaved changes?" msgstr "Discard unsaved changes?"
+38
View File
@@ -0,0 +1,38 @@
msgid ""
msgstr ""
"Project-Id-Version: ExampleApp 1.0\n"
"Language: es\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n==1 ? 0 : 1);\n"
#: ui/menu.c:10
msgid "ui.title"
msgstr ""
"Bienvenido"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.gameplay"
msgstr "Jugabilidad"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.input"
msgstr "Entrada"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.display"
msgstr "Pantalla"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.audio"
msgstr "Audio"
msgid "ui.settings.input.deadzone"
msgstr "Zona muerta"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.apply"
msgstr "Aplicar"
#: src/dusk/ui/frame/uiconfirm.c
msgid "ui.confirm.discard_changes"
msgstr "¿Descartar los cambios no guardados?"
+38
View File
@@ -0,0 +1,38 @@
msgid ""
msgstr ""
"Project-Id-Version: ExampleApp 1.0\n"
"Language: ja\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=1; plural=(0);\n"
#: ui/menu.c:10
msgid "ui.title"
msgstr ""
"歓迎"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.gameplay"
msgstr "ゲームプレイ"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.input"
msgstr "入力"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.display"
msgstr "表示"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.tabs.audio"
msgstr "オーディオ"
msgid "ui.settings.input.deadzone"
msgstr "デッドゾーン"
#: src/dusk/ui/frame/settings/uisettings.c
msgid "ui.settings.apply"
msgstr "適用"
#: src/dusk/ui/frame/uiconfirm.c
msgid "ui.confirm.discard_changes"
msgstr "未保存の変更を破棄しますか?"
+10
View File
@@ -16,4 +16,14 @@ typedef struct {
static const localeinfo_t LOCALE_EN_US = { static const localeinfo_t LOCALE_EN_US = {
.name = "en-US", .name = "en-US",
.file = "locale/en_US.po", .file = "locale/en_US.po",
};
static const localeinfo_t LOCALE_JP_JP = {
.name = "ja-JP",
.file = "locale/jp_JP.po",
};
static const localeinfo_t LOCALE_ES_MX = {
.name = "es-MX",
.file = "locale/es_MX.po",
}; };
@@ -6,7 +6,6 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
uisettings.c uisettings.c
uisettingsdiscard.c
uisettingsgameplay.c uisettingsgameplay.c
uisettingsinput.c uisettingsinput.c
uisettingsdisplay.c uisettingsdisplay.c
+72 -35
View File
@@ -11,6 +11,7 @@
#include "uisettingsdisplay.h" #include "uisettingsdisplay.h"
#include "uisettingsaudio.h" #include "uisettingsaudio.h"
#include "ui/frame/uiframe.h" #include "ui/frame/uiframe.h"
#include "ui/frame/uiconfirm.h"
#include "util/memory.h" #include "util/memory.h"
#include "display/spritebatch/spritebatch.h" #include "display/spritebatch/spritebatch.h"
#include "display/text/text.h" #include "display/text/text.h"
@@ -19,29 +20,23 @@
#include "locale/localemanager.h" #include "locale/localemanager.h"
#include "asset/loader/locale/assetlocaleloader.h" #include "asset/loader/locale/assetlocaleloader.h"
#define UI_SETTINGS_DISCARD_TEXT_MAX 128
typedef struct { typedef struct {
const char_t *localeId; const char_t *localeId;
errorret_t (*init)(void); errorret_t (*init)(void);
errorret_t (*draw)( uimenu_t *menu;
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
errorret_t (*update)(void);
void (*open)(void);
void (*load)(void); void (*load)(void);
void (*apply)(void); void (*apply)(void);
bool_t (*hasChanges)(void); bool_t (*hasChanges)(void);
bool_t pendingDiscardConfirm;
} uisettingstabdef_t; } uisettingstabdef_t;
static const uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = { static uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = {
[UI_SETTINGS_TAB_GAMEPLAY] = { [UI_SETTINGS_TAB_GAMEPLAY] = {
.localeId = "ui.settings.tabs.gameplay", .localeId = "ui.settings.tabs.gameplay",
.init = uiSettingsGameplayInit, .init = uiSettingsGameplayInit,
.draw = uiSettingsGameplayDraw, .menu = &UI_SETTINGS_GAMEPLAY.menu,
.update = uiSettingsGameplayUpdate,
.open = uiSettingsGameplayOpen,
.load = uiSettingsGameplayLoad, .load = uiSettingsGameplayLoad,
.apply = uiSettingsGameplayApply, .apply = uiSettingsGameplayApply,
.hasChanges = uiSettingsGameplayHasChanges .hasChanges = uiSettingsGameplayHasChanges
@@ -50,9 +45,7 @@ static const uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = {
[UI_SETTINGS_TAB_INPUT] = { [UI_SETTINGS_TAB_INPUT] = {
.localeId = "ui.settings.tabs.input", .localeId = "ui.settings.tabs.input",
.init = uiSettingsInputInit, .init = uiSettingsInputInit,
.draw = uiSettingsInputDraw, .menu = &UI_SETTINGS_INPUT.menu,
.update = uiSettingsInputUpdate,
.open = uiSettingsInputOpen,
.load = uiSettingsInputLoad, .load = uiSettingsInputLoad,
.apply = uiSettingsInputApply, .apply = uiSettingsInputApply,
.hasChanges = uiSettingsInputHasChanges .hasChanges = uiSettingsInputHasChanges
@@ -61,9 +54,7 @@ static const uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = {
[UI_SETTINGS_TAB_DISPLAY] = { [UI_SETTINGS_TAB_DISPLAY] = {
.localeId = "ui.settings.tabs.display", .localeId = "ui.settings.tabs.display",
.init = uiSettingsDisplayInit, .init = uiSettingsDisplayInit,
.draw = uiSettingsDisplayDraw, .menu = &UI_SETTINGS_DISPLAY.menu,
.update = uiSettingsDisplayUpdate,
.open = uiSettingsDisplayOpen,
.load = uiSettingsDisplayLoad, .load = uiSettingsDisplayLoad,
.apply = uiSettingsDisplayApply, .apply = uiSettingsDisplayApply,
.hasChanges = uiSettingsDisplayHasChanges .hasChanges = uiSettingsDisplayHasChanges
@@ -72,9 +63,7 @@ static const uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = {
[UI_SETTINGS_TAB_AUDIO] = { [UI_SETTINGS_TAB_AUDIO] = {
.localeId = "ui.settings.tabs.audio", .localeId = "ui.settings.tabs.audio",
.init = uiSettingsAudioInit, .init = uiSettingsAudioInit,
.draw = uiSettingsAudioDraw, .menu = &UI_SETTINGS_AUDIO.menu,
.update = uiSettingsAudioUpdate,
.open = uiSettingsAudioOpen,
.load = uiSettingsAudioLoad, .load = uiSettingsAudioLoad,
.apply = uiSettingsAudioApply, .apply = uiSettingsAudioApply,
.hasChanges = uiSettingsAudioHasChanges .hasChanges = uiSettingsAudioHasChanges
@@ -83,17 +72,22 @@ static const uisettingstabdef_t UI_SETTINGS_TAB_DEFS[UI_SETTINGS_TAB_COUNT] = {
uisettings_t UI_SETTINGS; uisettings_t UI_SETTINGS;
static uisettingstabdef_t UI_SETTINGS_TOP_DEF = {
.menu = &UI_SETTINGS.tabsMenu,
.load = uiSettingsLoad,
.hasChanges = uiSettingsHasChanges
};
errorret_t uiSettingsDiscardUpdate(uisettingstabdef_t *def);
void uiSettingsDiscardConfirmResult(const bool_t result, void *user);
void uiSettingsTabSelected( void uiSettingsTabSelected(
const uimenu_t *menu, const uimenu_t *menu,
const uint8_t index, const uint8_t index,
const uimenuitem_t *item const uimenuitem_t *item
) { ) {
if(index >= UI_SETTINGS_TAB_COUNT) return; if(index >= UI_SETTINGS_TAB_COUNT) return;
UI_SETTINGS_TAB_DEFS[index].open(); uiMenuOpen(UI_SETTINGS_TAB_DEFS[index].menu);
}
void uiSettingsTabsClosed(const uimenu_t *menu) {
uiSettingsDiscardClosed(&UI_SETTINGS.discard);
} }
errorret_t uiSettingsInit(void) { errorret_t uiSettingsInit(void) {
@@ -111,20 +105,26 @@ errorret_t uiSettingsInit(void) {
MENU_BEGIN( MENU_BEGIN(
&UI_SETTINGS.tabsMenu, UI_SETTINGS.tabs, uiSettingsTabSelected, &UI_SETTINGS.tabsMenu, UI_SETTINGS.tabs, uiSettingsTabSelected,
uiSettingsTabsClosed, NULL uiSettingsDiscardMenuClosed, NULL
); );
for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) { for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) {
MENU_TAB(UI_SETTINGS.tabLabels[i]); MENU_TAB(UI_SETTINGS.tabLabels[i]);
} }
MENU_END(UI_SETTINGS.tabs, menuIndex); MENU_END(UI_SETTINGS.tabs, menuIndex);
uiSettingsDiscardInit( UI_SETTINGS.tabsMenu.user = &UI_SETTINGS_TOP_DEF;
&UI_SETTINGS.discard, &UI_SETTINGS.tabsMenu, uiSettingsHasChanges,
uiSettingsLoad errorChain(assetLocaleGetString(
); &LOCALE.entry->data.locale,
"ui.settings.apply",
0,
UI_SETTINGS.applyLabel,
UI_SETTINGS_APPLY_LABEL_MAX
));
for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) { for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) {
errorChain(UI_SETTINGS_TAB_DEFS[i].init()); errorChain(UI_SETTINGS_TAB_DEFS[i].init());
UI_SETTINGS_TAB_DEFS[i].menu->user = &UI_SETTINGS_TAB_DEFS[i];
} }
errorOk(); errorOk();
@@ -161,8 +161,8 @@ errorret_t uiSettingsDraw(void) {
for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) { for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) {
if(!uiTabIsActive(&UI_SETTINGS.tabs[i].tab)) continue; if(!uiTabIsActive(&UI_SETTINGS.tabs[i].tab)) continue;
errorChain(UI_SETTINGS_TAB_DEFS[i].draw( errorChain(uiMenuDraw(
contentX, pageY, contentWidth, pageHeight UI_SETTINGS_TAB_DEFS[i].menu, contentX, pageY, contentWidth, pageHeight
)); ));
break; break;
} }
@@ -173,10 +173,10 @@ errorret_t uiSettingsDraw(void) {
errorret_t uiSettingsUpdate(void) { errorret_t uiSettingsUpdate(void) {
for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) { for(uint8_t i = 0; i < UI_SETTINGS_TAB_COUNT; i++) {
errorChain(UI_SETTINGS_TAB_DEFS[i].update()); errorChain(uiSettingsDiscardUpdate(&UI_SETTINGS_TAB_DEFS[i]));
} }
return uiSettingsDiscardUpdate(&UI_SETTINGS.discard); return uiSettingsDiscardUpdate(&UI_SETTINGS_TOP_DEF);
} }
bool_t uiSettingsIsOpen(void) { bool_t uiSettingsIsOpen(void) {
@@ -214,3 +214,40 @@ bool_t uiSettingsHasChanges(void) {
} }
return false; return false;
} }
void uiSettingsDiscardMenuClosed(const uimenu_t *menu) {
uisettingstabdef_t *def = (uisettingstabdef_t *)menu->user;
if(def->hasChanges()) def->pendingDiscardConfirm = true;
}
errorret_t uiSettingsDiscardUpdate(uisettingstabdef_t *def) {
if(!def->pendingDiscardConfirm) errorOk();
def->pendingDiscardConfirm = false;
char_t text[UI_SETTINGS_DISCARD_TEXT_MAX];
errorChain(assetLocaleGetString(
&LOCALE.entry->data.locale,
"ui.confirm.discard_changes",
0,
text,
UI_SETTINGS_DISCARD_TEXT_MAX
));
uiConfirmOpen(text, uiSettingsDiscardConfirmResult, def);
errorOk();
}
void uiSettingsDiscardConfirmResult(const bool_t result, void *user) {
uisettingstabdef_t *def = (uisettingstabdef_t *)user;
if(!result) {
// Cancel means "keep editing" - reopen without reloading so the
// unsaved widget values the user had are preserved.
uiMenuOpen(def->menu);
return;
}
// Confirmed - reload the widgets back to the actual engine values.
def->load();
}
+12 -2
View File
@@ -8,7 +8,6 @@
#pragma once #pragma once
#include "error/error.h" #include "error/error.h"
#include "ui/widget/uimenu.h" #include "ui/widget/uimenu.h"
#include "uisettingsdiscard.h"
#define UI_SETTINGS_TAB_GAMEPLAY 0 #define UI_SETTINGS_TAB_GAMEPLAY 0
#define UI_SETTINGS_TAB_INPUT 1 #define UI_SETTINGS_TAB_INPUT 1
@@ -16,16 +15,27 @@
#define UI_SETTINGS_TAB_AUDIO 3 #define UI_SETTINGS_TAB_AUDIO 3
#define UI_SETTINGS_TAB_COUNT 4 #define UI_SETTINGS_TAB_COUNT 4
#define UI_SETTINGS_TAB_LABEL_MAX 32 #define UI_SETTINGS_TAB_LABEL_MAX 32
#define UI_SETTINGS_APPLY_LABEL_MAX 32
typedef struct { typedef struct {
uimenu_t tabsMenu; uimenu_t tabsMenu;
uimenuitem_t tabs[UI_SETTINGS_TAB_COUNT]; uimenuitem_t tabs[UI_SETTINGS_TAB_COUNT];
char_t tabLabels[UI_SETTINGS_TAB_COUNT][UI_SETTINGS_TAB_LABEL_MAX]; char_t tabLabels[UI_SETTINGS_TAB_COUNT][UI_SETTINGS_TAB_LABEL_MAX];
uisettingsdiscard_t discard; char_t applyLabel[UI_SETTINGS_APPLY_LABEL_MAX];
} uisettings_t; } uisettings_t;
extern uisettings_t UI_SETTINGS; extern uisettings_t UI_SETTINGS;
/**
* Menu closed callback that flags a pending discard-changes
* confirmation if the menu's settings page/panel reports unsaved
* changes. Pass this directly as a settings page menu's closed
* callback.
*
* @param menu The menu that was just closed.
*/
void uiSettingsDiscardMenuClosed(const uimenu_t *menu);
/** /**
* Initializes the settings panel and all of its category pages. * Initializes the settings panel and all of its category pages.
* *
+3 -36
View File
@@ -18,10 +18,7 @@ void uiSettingsAudioSelected(
) { ) {
if(index != UI_SETTINGS_AUDIO_INDEX_APPLY) return; if(index != UI_SETTINGS_AUDIO_INDEX_APPLY) return;
uiSettingsAudioApply(); uiSettingsAudioApply();
} uiMenuClose(&UI_SETTINGS_AUDIO.menu);
void uiSettingsAudioClosed(const uimenu_t *menu) {
uiSettingsDiscardClosed(&UI_SETTINGS_AUDIO.discard);
} }
errorret_t uiSettingsAudioInit(void) { errorret_t uiSettingsAudioInit(void) {
@@ -29,46 +26,16 @@ errorret_t uiSettingsAudioInit(void) {
MENU_BEGIN( MENU_BEGIN(
&UI_SETTINGS_AUDIO.menu, UI_SETTINGS_AUDIO.items, &UI_SETTINGS_AUDIO.menu, UI_SETTINGS_AUDIO.items,
uiSettingsAudioSelected, uiSettingsAudioClosed, NULL uiSettingsAudioSelected, uiSettingsDiscardMenuClosed, NULL
); );
MENU_LABEL("No audio settings yet"); MENU_LABEL("No audio settings yet");
MENU_BUTTON("Apply"); MENU_BUTTON(UI_SETTINGS.applyLabel);
MENU_END(UI_SETTINGS_AUDIO.items, 1); MENU_END(UI_SETTINGS_AUDIO.items, 1);
uiSettingsDiscardInit(
&UI_SETTINGS_AUDIO.discard, &UI_SETTINGS_AUDIO.menu,
uiSettingsAudioHasChanges, uiSettingsAudioLoad
);
errorOk(); errorOk();
} }
errorret_t uiSettingsAudioDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
) {
return uiMenuDraw(&UI_SETTINGS_AUDIO.menu, x, y, width, height);
}
bool_t uiSettingsAudioIsOpen(void) {
return uiMenuIsActive(&UI_SETTINGS_AUDIO.menu);
}
void uiSettingsAudioOpen(void) {
uiMenuOpen(&UI_SETTINGS_AUDIO.menu);
}
void uiSettingsAudioClose(void) {
uiMenuClose(&UI_SETTINGS_AUDIO.menu);
}
errorret_t uiSettingsAudioUpdate(void) {
return uiSettingsDiscardUpdate(&UI_SETTINGS_AUDIO.discard);
}
void uiSettingsAudioLoad(void) { void uiSettingsAudioLoad(void) {
} }
+1 -43
View File
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include "error/error.h" #include "error/error.h"
#include "ui/widget/uimenu.h" #include "ui/widget/uimenu.h"
#include "uisettingsdiscard.h" #include "uisettings.h"
#define UI_SETTINGS_AUDIO_ITEM_COUNT 2 #define UI_SETTINGS_AUDIO_ITEM_COUNT 2
#define UI_SETTINGS_AUDIO_INDEX_APPLY 1 #define UI_SETTINGS_AUDIO_INDEX_APPLY 1
@@ -16,7 +16,6 @@
typedef struct { typedef struct {
uimenu_t menu; uimenu_t menu;
uimenuitem_t items[UI_SETTINGS_AUDIO_ITEM_COUNT]; uimenuitem_t items[UI_SETTINGS_AUDIO_ITEM_COUNT];
uisettingsdiscard_t discard;
} uisettingsaudio_t; } uisettingsaudio_t;
extern uisettingsaudio_t UI_SETTINGS_AUDIO; extern uisettingsaudio_t UI_SETTINGS_AUDIO;
@@ -28,47 +27,6 @@ extern uisettingsaudio_t UI_SETTINGS_AUDIO;
*/ */
errorret_t uiSettingsAudioInit(void); errorret_t uiSettingsAudioInit(void);
/**
* Draws the audio settings page at the given content rect.
*
* @param x Screen x position.
* @param y Screen y position.
* @param width Content width.
* @param height Content height.
* @return Any error that occurs.
*/
errorret_t uiSettingsAudioDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
/**
* Updates the audio settings page. Shows a discard-changes
* confirmation if the page was just backed out of with unsaved changes.
*
* @return Any error that occurs.
*/
errorret_t uiSettingsAudioUpdate(void);
/**
* Returns true when the audio settings page is currently open.
*
* @returns True if open.
*/
bool_t uiSettingsAudioIsOpen(void);
/**
* Opens the audio settings page. No-op when already open.
*/
void uiSettingsAudioOpen(void);
/**
* Closes the audio settings page. No-op when already closed.
*/
void uiSettingsAudioClose(void);
/** /**
* Loads the page's widgets from the current engine audio settings. * Loads the page's widgets from the current engine audio settings.
*/ */
@@ -1,59 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uisettingsdiscard.h"
#include "ui/frame/uiconfirm.h"
#include "locale/localemanager.h"
#include "asset/loader/locale/assetlocaleloader.h"
void uiSettingsDiscardInit(
uisettingsdiscard_t *discard,
uimenu_t *menu,
uisettingshaschangesfn_t hasChanges,
uisettingsloadfn_t load
) {
discard->menu = menu;
discard->hasChanges = hasChanges;
discard->load = load;
discard->pending = false;
}
void uiSettingsDiscardClosed(uisettingsdiscard_t *discard) {
if(discard->hasChanges()) discard->pending = true;
}
errorret_t uiSettingsDiscardUpdate(uisettingsdiscard_t *discard) {
if(!discard->pending) errorOk();
discard->pending = false;
char_t text[UI_SETTINGS_DISCARD_TEXT_MAX];
errorChain(assetLocaleGetString(
&LOCALE.entry->data.locale,
"ui.confirm.discard_changes",
0,
text,
UI_SETTINGS_DISCARD_TEXT_MAX
));
uiConfirmOpen(text, uiSettingsDiscardConfirmResult, discard);
errorOk();
}
void uiSettingsDiscardConfirmResult(const bool_t result, void *user) {
uisettingsdiscard_t *discard = (uisettingsdiscard_t *)user;
if(!result) {
// Cancel means "keep editing" - reopen without reloading so the
// unsaved widget values the user had are preserved.
uiMenuOpen(discard->menu);
return;
}
// Confirmed - reload the widgets back to the actual engine values.
discard->load();
}
@@ -1,77 +0,0 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "ui/widget/uimenu.h"
#define UI_SETTINGS_DISCARD_TEXT_MAX 128
/**
* Returns true if the owning settings page/panel has unsaved changes.
*
* @returns True if there are unsaved changes.
*/
typedef bool_t (*uisettingshaschangesfn_t)(void);
/**
* Reloads the owning settings page/panel's widgets from the current
* engine settings.
*/
typedef void (*uisettingsloadfn_t)(void);
typedef struct {
uimenu_t *menu;
uisettingshaschangesfn_t hasChanges;
uisettingsloadfn_t load;
bool_t pending;
} uisettingsdiscard_t;
/**
* Initializes a discard-changes confirmation helper for a settings
* page or panel.
*
* @param discard The helper state to initialize.
* @param menu The menu to reopen if the user cancels discarding.
* @param hasChanges Callback returning true if there are unsaved
* changes.
* @param load Callback that reloads the widgets from the current
* engine settings, called if the user confirms discarding changes.
*/
void uiSettingsDiscardInit(
uisettingsdiscard_t *discard,
uimenu_t *menu,
uisettingshaschangesfn_t hasChanges,
uisettingsloadfn_t load
);
/**
* Call from the owning menu's closed callback. Flags a pending
* confirmation if hasChanges() reports unsaved changes.
*
* @param discard The helper state.
*/
void uiSettingsDiscardClosed(uisettingsdiscard_t *discard);
/**
* Call every frame from the owning page/panel's update function. Shows
* the discard-changes confirmation dialog if one is pending.
*
* @param discard The helper state.
* @return Any error that occurs.
*/
errorret_t uiSettingsDiscardUpdate(uisettingsdiscard_t *discard);
/**
* Callback passed to uiConfirmOpen by uiSettingsDiscardUpdate. Reopens
* the menu if the user chose to keep editing.
*
* @param result True if the user confirmed discarding changes, false
* to keep editing. On true, the widgets are reloaded via load().
* @param user The uisettingsdiscard_t* this confirmation belongs to.
*/
void uiSettingsDiscardConfirmResult(const bool_t result, void *user);
+3 -36
View File
@@ -18,10 +18,7 @@ void uiSettingsDisplaySelected(
) { ) {
if(index != UI_SETTINGS_DISPLAY_INDEX_APPLY) return; if(index != UI_SETTINGS_DISPLAY_INDEX_APPLY) return;
uiSettingsDisplayApply(); uiSettingsDisplayApply();
} uiMenuClose(&UI_SETTINGS_DISPLAY.menu);
void uiSettingsDisplayClosed(const uimenu_t *menu) {
uiSettingsDiscardClosed(&UI_SETTINGS_DISPLAY.discard);
} }
errorret_t uiSettingsDisplayInit(void) { errorret_t uiSettingsDisplayInit(void) {
@@ -29,46 +26,16 @@ errorret_t uiSettingsDisplayInit(void) {
MENU_BEGIN( MENU_BEGIN(
&UI_SETTINGS_DISPLAY.menu, UI_SETTINGS_DISPLAY.items, &UI_SETTINGS_DISPLAY.menu, UI_SETTINGS_DISPLAY.items,
uiSettingsDisplaySelected, uiSettingsDisplayClosed, NULL uiSettingsDisplaySelected, uiSettingsDiscardMenuClosed, NULL
); );
MENU_LABEL("No display settings yet"); MENU_LABEL("No display settings yet");
MENU_BUTTON("Apply"); MENU_BUTTON(UI_SETTINGS.applyLabel);
MENU_END(UI_SETTINGS_DISPLAY.items, 1); MENU_END(UI_SETTINGS_DISPLAY.items, 1);
uiSettingsDiscardInit(
&UI_SETTINGS_DISPLAY.discard, &UI_SETTINGS_DISPLAY.menu,
uiSettingsDisplayHasChanges, uiSettingsDisplayLoad
);
errorOk(); errorOk();
} }
errorret_t uiSettingsDisplayDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
) {
return uiMenuDraw(&UI_SETTINGS_DISPLAY.menu, x, y, width, height);
}
bool_t uiSettingsDisplayIsOpen(void) {
return uiMenuIsActive(&UI_SETTINGS_DISPLAY.menu);
}
void uiSettingsDisplayOpen(void) {
uiMenuOpen(&UI_SETTINGS_DISPLAY.menu);
}
void uiSettingsDisplayClose(void) {
uiMenuClose(&UI_SETTINGS_DISPLAY.menu);
}
errorret_t uiSettingsDisplayUpdate(void) {
return uiSettingsDiscardUpdate(&UI_SETTINGS_DISPLAY.discard);
}
void uiSettingsDisplayLoad(void) { void uiSettingsDisplayLoad(void) {
} }
+1 -43
View File
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include "error/error.h" #include "error/error.h"
#include "ui/widget/uimenu.h" #include "ui/widget/uimenu.h"
#include "uisettingsdiscard.h" #include "uisettings.h"
#define UI_SETTINGS_DISPLAY_ITEM_COUNT 2 #define UI_SETTINGS_DISPLAY_ITEM_COUNT 2
#define UI_SETTINGS_DISPLAY_INDEX_APPLY 1 #define UI_SETTINGS_DISPLAY_INDEX_APPLY 1
@@ -16,7 +16,6 @@
typedef struct { typedef struct {
uimenu_t menu; uimenu_t menu;
uimenuitem_t items[UI_SETTINGS_DISPLAY_ITEM_COUNT]; uimenuitem_t items[UI_SETTINGS_DISPLAY_ITEM_COUNT];
uisettingsdiscard_t discard;
} uisettingsdisplay_t; } uisettingsdisplay_t;
extern uisettingsdisplay_t UI_SETTINGS_DISPLAY; extern uisettingsdisplay_t UI_SETTINGS_DISPLAY;
@@ -28,47 +27,6 @@ extern uisettingsdisplay_t UI_SETTINGS_DISPLAY;
*/ */
errorret_t uiSettingsDisplayInit(void); errorret_t uiSettingsDisplayInit(void);
/**
* Draws the display settings page at the given content rect.
*
* @param x Screen x position.
* @param y Screen y position.
* @param width Content width.
* @param height Content height.
* @return Any error that occurs.
*/
errorret_t uiSettingsDisplayDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
/**
* Updates the display settings page. Shows a discard-changes
* confirmation if the page was just backed out of with unsaved changes.
*
* @return Any error that occurs.
*/
errorret_t uiSettingsDisplayUpdate(void);
/**
* Returns true when the display settings page is currently open.
*
* @returns True if open.
*/
bool_t uiSettingsDisplayIsOpen(void);
/**
* Opens the display settings page. No-op when already open.
*/
void uiSettingsDisplayOpen(void);
/**
* Closes the display settings page. No-op when already closed.
*/
void uiSettingsDisplayClose(void);
/** /**
* Loads the page's widgets from the current engine display settings. * Loads the page's widgets from the current engine display settings.
*/ */
@@ -31,63 +31,30 @@ void uiSettingsGameplaySelected(
if(index == UI_SETTINGS_GAMEPLAY_INDEX_APPLY) { if(index == UI_SETTINGS_GAMEPLAY_INDEX_APPLY) {
uiSettingsGameplayApply(); uiSettingsGameplayApply();
uiMenuClose(&UI_SETTINGS_GAMEPLAY.menu);
return; return;
} }
} }
void uiSettingsGameplayClosed(const uimenu_t *menu) {
uiSettingsDiscardClosed(&UI_SETTINGS_GAMEPLAY.discard);
}
errorret_t uiSettingsGameplayInit(void) { errorret_t uiSettingsGameplayInit(void) {
memoryZero(&UI_SETTINGS_GAMEPLAY, sizeof(uisettingsgameplay_t)); memoryZero(&UI_SETTINGS_GAMEPLAY, sizeof(uisettingsgameplay_t));
MENU_BEGIN( MENU_BEGIN(
&UI_SETTINGS_GAMEPLAY.menu, UI_SETTINGS_GAMEPLAY.items, &UI_SETTINGS_GAMEPLAY.menu, UI_SETTINGS_GAMEPLAY.items,
uiSettingsGameplaySelected, uiSettingsGameplayClosed, NULL uiSettingsGameplaySelected, uiSettingsDiscardMenuClosed, NULL
); );
MENU_BUTTON("Do thing"); MENU_BUTTON("Do thing");
MENU_BUTTON("Do other thing"); MENU_BUTTON("Do other thing");
MENU_CHECKBOX("Enable thing?"); MENU_CHECKBOX("Enable thing?");
MENU_SLIDER_FLOAT("test", 1.0f, 1.0f, 4.0f, 0.5f); MENU_SLIDER_FLOAT("test", 1.0f, 1.0f, 4.0f, 0.5f);
MENU_BUTTON("Show confirm"); MENU_BUTTON("Show confirm");
MENU_BUTTON("Apply"); MENU_BUTTON(UI_SETTINGS.applyLabel);
MENU_END(UI_SETTINGS_GAMEPLAY.items, 1); MENU_END(UI_SETTINGS_GAMEPLAY.items, 1);
uiSettingsDiscardInit(
&UI_SETTINGS_GAMEPLAY.discard, &UI_SETTINGS_GAMEPLAY.menu,
uiSettingsGameplayHasChanges, uiSettingsGameplayLoad
);
errorOk(); errorOk();
} }
errorret_t uiSettingsGameplayDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
) {
return uiMenuDraw(&UI_SETTINGS_GAMEPLAY.menu, x, y, width, height);
}
bool_t uiSettingsGameplayIsOpen(void) {
return uiMenuIsActive(&UI_SETTINGS_GAMEPLAY.menu);
}
void uiSettingsGameplayOpen(void) {
uiMenuOpen(&UI_SETTINGS_GAMEPLAY.menu);
}
void uiSettingsGameplayClose(void) {
uiMenuClose(&UI_SETTINGS_GAMEPLAY.menu);
}
errorret_t uiSettingsGameplayUpdate(void) {
return uiSettingsDiscardUpdate(&UI_SETTINGS_GAMEPLAY.discard);
}
void uiSettingsGameplayLoad(void) { void uiSettingsGameplayLoad(void) {
UI_SETTINGS_GAMEPLAY.loadedEnableThing = uiCheckboxIsChecked( UI_SETTINGS_GAMEPLAY.loadedEnableThing = uiCheckboxIsChecked(
&UI_SETTINGS_GAMEPLAY.items[UI_SETTINGS_GAMEPLAY_INDEX_ENABLE_THING].checkbox &UI_SETTINGS_GAMEPLAY.items[UI_SETTINGS_GAMEPLAY_INDEX_ENABLE_THING].checkbox
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include "error/error.h" #include "error/error.h"
#include "ui/widget/uimenu.h" #include "ui/widget/uimenu.h"
#include "uisettingsdiscard.h" #include "uisettings.h"
#define UI_SETTINGS_GAMEPLAY_ITEM_COUNT 6 #define UI_SETTINGS_GAMEPLAY_ITEM_COUNT 6
#define UI_SETTINGS_GAMEPLAY_INDEX_ENABLE_THING 2 #define UI_SETTINGS_GAMEPLAY_INDEX_ENABLE_THING 2
@@ -19,7 +19,6 @@
typedef struct { typedef struct {
uimenu_t menu; uimenu_t menu;
uimenuitem_t items[UI_SETTINGS_GAMEPLAY_ITEM_COUNT]; uimenuitem_t items[UI_SETTINGS_GAMEPLAY_ITEM_COUNT];
uisettingsdiscard_t discard;
bool_t loadedEnableThing; bool_t loadedEnableThing;
float_t loadedTestValue; float_t loadedTestValue;
} uisettingsgameplay_t; } uisettingsgameplay_t;
@@ -33,47 +32,6 @@ extern uisettingsgameplay_t UI_SETTINGS_GAMEPLAY;
*/ */
errorret_t uiSettingsGameplayInit(void); errorret_t uiSettingsGameplayInit(void);
/**
* Draws the gameplay settings page at the given content rect.
*
* @param x Screen x position.
* @param y Screen y position.
* @param width Content width.
* @param height Content height.
* @return Any error that occurs.
*/
errorret_t uiSettingsGameplayDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
/**
* Updates the gameplay settings page. Shows a discard-changes
* confirmation if the page was just backed out of with unsaved changes.
*
* @return Any error that occurs.
*/
errorret_t uiSettingsGameplayUpdate(void);
/**
* Returns true when the gameplay settings page is currently open.
*
* @returns True if open.
*/
bool_t uiSettingsGameplayIsOpen(void);
/**
* Opens the gameplay settings page. No-op when already open.
*/
void uiSettingsGameplayOpen(void);
/**
* Closes the gameplay settings page. No-op when already closed.
*/
void uiSettingsGameplayClose(void);
/** /**
* Loads the page's widgets from the current engine gameplay settings. * Loads the page's widgets from the current engine gameplay settings.
*/ */
+5 -36
View File
@@ -21,10 +21,7 @@ void uiSettingsInputSelected(
) { ) {
if(index != UI_SETTINGS_INPUT_INDEX_APPLY) return; if(index != UI_SETTINGS_INPUT_INDEX_APPLY) return;
uiSettingsInputApply(); uiSettingsInputApply();
} uiMenuClose(&UI_SETTINGS_INPUT.menu);
void uiSettingsInputClosed(const uimenu_t *menu) {
uiSettingsDiscardClosed(&UI_SETTINGS_INPUT.discard);
} }
errorret_t uiSettingsInputInit(void) { errorret_t uiSettingsInputInit(void) {
@@ -32,7 +29,7 @@ errorret_t uiSettingsInputInit(void) {
MENU_BEGIN( MENU_BEGIN(
&UI_SETTINGS_INPUT.menu, UI_SETTINGS_INPUT.items, &UI_SETTINGS_INPUT.menu, UI_SETTINGS_INPUT.items,
uiSettingsInputSelected, uiSettingsInputClosed, NULL uiSettingsInputSelected, uiSettingsDiscardMenuClosed, NULL
); );
#ifdef DUSK_INPUT_GAMEPAD #ifdef DUSK_INPUT_GAMEPAD
errorChain(assetLocaleGetString( errorChain(assetLocaleGetString(
@@ -48,42 +45,13 @@ errorret_t uiSettingsInputInit(void) {
#else #else
MENU_LABEL("No input settings yet"); MENU_LABEL("No input settings yet");
#endif #endif
MENU_BUTTON("Apply");
MENU_BUTTON(UI_SETTINGS.applyLabel);
MENU_END(UI_SETTINGS_INPUT.items, 1); MENU_END(UI_SETTINGS_INPUT.items, 1);
uiSettingsDiscardInit(
&UI_SETTINGS_INPUT.discard, &UI_SETTINGS_INPUT.menu,
uiSettingsInputHasChanges, uiSettingsInputLoad
);
errorOk(); errorOk();
} }
errorret_t uiSettingsInputDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
) {
return uiMenuDraw(&UI_SETTINGS_INPUT.menu, x, y, width, height);
}
bool_t uiSettingsInputIsOpen(void) {
return uiMenuIsActive(&UI_SETTINGS_INPUT.menu);
}
void uiSettingsInputOpen(void) {
uiMenuOpen(&UI_SETTINGS_INPUT.menu);
}
void uiSettingsInputClose(void) {
uiMenuClose(&UI_SETTINGS_INPUT.menu);
}
errorret_t uiSettingsInputUpdate(void) {
return uiSettingsDiscardUpdate(&UI_SETTINGS_INPUT.discard);
}
void uiSettingsInputLoad(void) { void uiSettingsInputLoad(void) {
#ifdef DUSK_INPUT_GAMEPAD #ifdef DUSK_INPUT_GAMEPAD
uiSliderSetFloat( uiSliderSetFloat(
@@ -107,5 +75,6 @@ bool_t uiSettingsInputHasChanges(void) {
&UI_SETTINGS_INPUT.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider &UI_SETTINGS_INPUT.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider
) != INPUT.deadzone) return true; ) != INPUT.deadzone) return true;
#endif #endif
return false; return false;
} }
+1 -43
View File
@@ -8,7 +8,7 @@
#pragma once #pragma once
#include "error/error.h" #include "error/error.h"
#include "ui/widget/uimenu.h" #include "ui/widget/uimenu.h"
#include "uisettingsdiscard.h" #include "uisettings.h"
#define UI_SETTINGS_INPUT_ITEM_COUNT 2 #define UI_SETTINGS_INPUT_ITEM_COUNT 2
#define UI_SETTINGS_INPUT_LABEL_MAX 32 #define UI_SETTINGS_INPUT_LABEL_MAX 32
@@ -18,7 +18,6 @@
typedef struct { typedef struct {
uimenu_t menu; uimenu_t menu;
uimenuitem_t items[UI_SETTINGS_INPUT_ITEM_COUNT]; uimenuitem_t items[UI_SETTINGS_INPUT_ITEM_COUNT];
uisettingsdiscard_t discard;
char_t deadzoneLabel[UI_SETTINGS_INPUT_LABEL_MAX]; char_t deadzoneLabel[UI_SETTINGS_INPUT_LABEL_MAX];
} uisettingsinput_t; } uisettingsinput_t;
@@ -31,47 +30,6 @@ extern uisettingsinput_t UI_SETTINGS_INPUT;
*/ */
errorret_t uiSettingsInputInit(void); errorret_t uiSettingsInputInit(void);
/**
* Draws the input settings page at the given content rect.
*
* @param x Screen x position.
* @param y Screen y position.
* @param width Content width.
* @param height Content height.
* @return Any error that occurs.
*/
errorret_t uiSettingsInputDraw(
const float_t x,
const float_t y,
const float_t width,
const float_t height
);
/**
* Updates the input settings page. Shows a discard-changes confirmation
* if the page was just backed out of with unsaved changes.
*
* @return Any error that occurs.
*/
errorret_t uiSettingsInputUpdate(void);
/**
* Returns true when the input settings page is currently open.
*
* @returns True if open.
*/
bool_t uiSettingsInputIsOpen(void);
/**
* Opens the input settings page. No-op when already open.
*/
void uiSettingsInputOpen(void);
/**
* Closes the input settings page. No-op when already closed.
*/
void uiSettingsInputClose(void);
/** /**
* Loads the page's widgets from the current engine input settings. * Loads the page's widgets from the current engine input settings.
*/ */
+2
View File
@@ -61,6 +61,8 @@ typedef struct uimenu_s {
uimenuselectedcallback_t selected; uimenuselectedcallback_t selected;
uimenuclosedcallback_t closed; uimenuclosedcallback_t closed;
uimenuchangedcallback_t changed; uimenuchangedcallback_t changed;
void *user;
} uimenu_t; } uimenu_t;
/** /**