diff --git a/assets/locale/en_US.po b/assets/locale/en_US.po index b9a6c6d0..fd4ee5df 100644 --- a/assets/locale/en_US.po +++ b/assets/locale/en_US.po @@ -24,6 +24,7 @@ msgstr "Try again" msgid "initial.no_device.continue" msgstr "Continue without saving" + # Main Menu Scene msgid "main_menu.new_game" msgstr "New Game" @@ -37,6 +38,19 @@ msgstr "Options" msgid "main_menu.quit" msgstr "Quit Game" +msgid "main_menu.quit_confirm" +msgstr "Are you sure you want to quit?" + + + + + + + + + + + #: ui/menu.c:10 msgid "ui.title" msgstr "" diff --git a/assets/locale/es_MX.po b/assets/locale/es_MX.po deleted file mode 100644 index 9f967759..00000000 --- a/assets/locale/es_MX.po +++ /dev/null @@ -1,194 +0,0 @@ -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.general" -msgstr "General" - -#: 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 "Deadzone" - -#: src/dusk/ui/frame/settings/uisettingsgeneral.c -msgid "ui.settings.general.language" -msgstr "Idioma" - -#: src/dusk/ui/frame/settings/uisettingsgeneral.c -msgid "ui.settings.general.language_detail" -msgstr "Se aplica después de reiniciar la aplicación." - -#: 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?" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.characters" -msgstr "Personajes" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.items" -msgstr "Objetos" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.settings" -msgstr "Configuración" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save" -msgstr "Guardar" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_success" -msgstr "Partida guardada." - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_cancelled" -msgstr "Guardado cancelado." - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_unavailable" -msgstr "No se puede guardar: no se encontró ningún dispositivo de guardado." - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_temporary" -msgstr "Esta sesión es temporal - no se encontró ningún dispositivo de guardado, por lo que guardar está deshabilitado." - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_create_confirm" -msgstr "No se encontraron datos guardados. ¿Crear una partida nueva?" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_failed_format" -msgstr "Error al guardar: %s" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_check_failed_format" -msgstr "No se puede guardar: %s" - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.message" -msgstr "No se encontró ningún dispositivo de guardado. Puedes continuar, pero\nel progreso no se guardará." - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.retry" -msgstr "Reintentar" - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.continue" -msgstr "Continuar de todos modos" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.message" -msgstr "No se encontraron datos guardados. ¿Crear una partida nueva?" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.yes" -msgstr "Sí" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.no" -msgstr "No" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.new_game" -msgstr "Nueva Partida" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.load_game" -msgstr "Cargar Partida" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.options" -msgstr "Opciones" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.quit" -msgstr "Salir del Juego" - -#: src/dusk/ui/frame/uiconfirm.c -msgid "ui.confirm.confirm" -msgstr "Confirmar" - -#: src/dusk/ui/frame/uiconfirm.c -msgid "ui.confirm.cancel" -msgstr "Cancelar" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.attack" -msgstr "Atacar" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.flee" -msgstr "Huir" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.target_format" -msgstr "Enemigo %u (%u/%u PS)" - -#: src/dusk/ui/frame/battle/uibattlehud.c -msgid "ui.battle.hud.hp_format" -msgstr "PS %u/%u" - -#: src/dusk/ui/frame/battle/uibattlehud.c -msgid "ui.battle.hud.mp_format" -msgstr "PM %u/%u" - -#: src/dusk/ui/frame/settings/uisettingsaudio.c -msgid "ui.settings.audio.placeholder" -msgstr "Aún no hay opciones de audio" - -#: src/dusk/ui/frame/settings/uisettingsdisplay.c -msgid "ui.settings.display.placeholder" -msgstr "Aún no hay opciones de pantalla" - -#: src/dusk/ui/frame/settings/uisettingsinput.c -msgid "ui.settings.input.placeholder" -msgstr "Aún no hay opciones de entrada" - -#: src/dusk/ui/frame/backpack/uibackpack.c -msgid "ui.backpack.category_format" -msgstr "Categoría %u" - -#: src/dusk/ui/overlay/uiloading.c -msgid "ui.loading.text" -msgstr "cargando" - -#: src/dusk/ui/overlay/uiautosave.c -msgid "ui.autosave.saving" -msgstr "GUARDANDO" - -#: src/dusk/rpg/item/item.json -msgid "item.potion.name" -msgstr "Poción" - -#: src/dusk/rpg/item/item.json -msgid "item.potato.name" -msgstr "Papa" - -#: src/dusk/rpg/item/item.json -msgid "item.apple.name" -msgstr "Manzana" diff --git a/assets/locale/jp_JP.po b/assets/locale/jp_JP.po deleted file mode 100644 index 27b5e074..00000000 --- a/assets/locale/jp_JP.po +++ /dev/null @@ -1,194 +0,0 @@ -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.general" -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/uisettingsgeneral.c -msgid "ui.settings.general.language" -msgstr "言語" - -#: src/dusk/ui/frame/settings/uisettingsgeneral.c -msgid "ui.settings.general.language_detail" -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 "未保存の変更を破棄しますか?" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.characters" -msgstr "キャラクター" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.items" -msgstr "アイテム" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.settings" -msgstr "設定" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save" -msgstr "セーブ" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_success" -msgstr "セーブしました。" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_cancelled" -msgstr "セーブをキャンセルしました。" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_unavailable" -msgstr "セーブできません - セーブデバイスが見つかりません。" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_temporary" -msgstr "このセッションは一時的です - セーブデバイスが見つからなかったため、セーブは無効になっています。" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_create_confirm" -msgstr "セーブデータが見つかりません。新しいセーブを作成しますか?" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_failed_format" -msgstr "セーブに失敗しました: %s" - -#: src/dusk/ui/frame/game/uigamemenu.c -msgid "ui.game_menu.save_check_failed_format" -msgstr "セーブできません: %s" - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.message" -msgstr "セーブデバイスが見つかりません。続行できますが、\n進行状況は保存されません。" - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.retry" -msgstr "再試行" - -#: src/dusk/ui/frame/initial/uiinitialnocard.c -msgid "ui.initial.no_card.continue" -msgstr "続行する" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.message" -msgstr "セーブデータが見つかりません。新しいセーブを作成しますか?" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.yes" -msgstr "はい" - -#: src/dusk/ui/frame/initial/uiinitialcreatesave.c -msgid "ui.initial.create_save.no" -msgstr "いいえ" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.new_game" -msgstr "ニューゲーム" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.load_game" -msgstr "ロードゲーム" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.options" -msgstr "オプション" - -#: src/dusk/ui/frame/mainmenu/uimainmenu.c -msgid "ui.main_menu.quit" -msgstr "ゲームを終了" - -#: src/dusk/ui/frame/uiconfirm.c -msgid "ui.confirm.confirm" -msgstr "確認" - -#: src/dusk/ui/frame/uiconfirm.c -msgid "ui.confirm.cancel" -msgstr "キャンセル" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.attack" -msgstr "攻撃" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.flee" -msgstr "逃げる" - -#: src/dusk/ui/frame/battle/uibattlemenu.c -msgid "ui.battle.menu.target_format" -msgstr "敵%u (%u/%u HP)" - -#: src/dusk/ui/frame/battle/uibattlehud.c -msgid "ui.battle.hud.hp_format" -msgstr "HP %u/%u" - -#: src/dusk/ui/frame/battle/uibattlehud.c -msgid "ui.battle.hud.mp_format" -msgstr "MP %u/%u" - -#: src/dusk/ui/frame/settings/uisettingsaudio.c -msgid "ui.settings.audio.placeholder" -msgstr "オーディオ設定はまだありません" - -#: src/dusk/ui/frame/settings/uisettingsdisplay.c -msgid "ui.settings.display.placeholder" -msgstr "表示設定はまだありません" - -#: src/dusk/ui/frame/settings/uisettingsinput.c -msgid "ui.settings.input.placeholder" -msgstr "入力設定はまだありません" - -#: src/dusk/ui/frame/backpack/uibackpack.c -msgid "ui.backpack.category_format" -msgstr "カテゴリー%u" - -#: src/dusk/ui/overlay/uiloading.c -msgid "ui.loading.text" -msgstr "読み込み中" - -#: src/dusk/ui/overlay/uiautosave.c -msgid "ui.autosave.saving" -msgstr "保存中" - -#: src/dusk/rpg/item/item.json -msgid "item.potion.name" -msgstr "ポーション" - -#: src/dusk/rpg/item/item.json -msgid "item.potato.name" -msgstr "ジャガイモ" - -#: src/dusk/rpg/item/item.json -msgid "item.apple.name" -msgstr "リンゴ" diff --git a/src/dusk/ui/frame/mainmenu/uimainmenu.c b/src/dusk/ui/frame/mainmenu/uimainmenu.c index f1163de8..6063898c 100644 --- a/src/dusk/ui/frame/mainmenu/uimainmenu.c +++ b/src/dusk/ui/frame/mainmenu/uimainmenu.c @@ -15,6 +15,7 @@ #include "assert/assert.h" #include "locale/localemanager.h" #include "asset/loader/locale/assetlocaleloader.h" +#include "ui/frame/uiconfirm.h" #define UI_MAIN_MENU_INDEX_NEW_GAME 0 #define UI_MAIN_MENU_INDEX_LOAD_GAME 1 @@ -23,15 +24,19 @@ uimainmenu_t UI_MAIN_MENU; +void uiMainMenuQuitConfirmed(const bool_t result, void *user) { + if(result) ENGINE.running = false; +} + void uiMainMenuSelected( const uimenu_t *menu, const uint8_t index, const uimenuitem_t *item ) { - uiMenuClose(&UI_MAIN_MENU.menu); switch(index) { case UI_MAIN_MENU_INDEX_NEW_GAME: + uiMenuClose(&UI_MAIN_MENU.menu); testBattleStart(); break; @@ -44,7 +49,7 @@ void uiMainMenuSelected( break; case UI_MAIN_MENU_INDEX_QUIT: - ENGINE.running = false; + uiConfirmOpen("main_menu.quit_confirm", uiMainMenuQuitConfirmed, NULL); break; default: diff --git a/src/dusk/ui/frame/uiconfirm.c b/src/dusk/ui/frame/uiconfirm.c index 76fe8fbd..e7da213d 100644 --- a/src/dusk/ui/frame/uiconfirm.c +++ b/src/dusk/ui/frame/uiconfirm.c @@ -6,117 +6,29 @@ */ #include "uiconfirm.h" -#include "ui/widget/uiframe.h" +#include "ui/widget/uimodal.h" #include "assert/assert.h" #include "util/memory.h" -#include "util/string.h" -#include "util/math.h" -#include "display/screen/screen.h" -#include "display/text/text.h" -#include "display/color.h" -#include "display/spritebatch/spritebatch.h" -#include "display/texture/texture.h" -#include "display/shader/shaderunlit.h" -#include "locale/localemanager.h" -#include "asset/loader/locale/assetlocaleloader.h" -#define UI_CONFIRM_BACKDROP_COLOR color4b(0, 0, 0, 160) +#define UI_CONFIRM_INDEX_CONFIRM 0 +#define UI_CONFIRM_INDEX_CANCEL 1 uiconfirm_t UI_CONFIRM; -void uiConfirmSelected( - const uimenu_t *menu, - const uint8_t index, - const uimenuitem_t *item -) { - UI_CONFIRM.result = index == UI_CONFIRM_INDEX_CONFIRM; - uiConfirmClose(); -} - -void uiConfirmClosed(const uimenu_t *menu) { +void uiConfirmModalCallback(const uint8_t optionIndex, void *user) { + UI_CONFIRM.result = optionIndex == UI_CONFIRM_INDEX_CONFIRM; if(UI_CONFIRM.callback != NULL) { - UI_CONFIRM.callback(UI_CONFIRM.result, UI_CONFIRM.user); + UI_CONFIRM.callback(UI_CONFIRM.result, user); } } errorret_t uiConfirmInit(void) { memoryZero(&UI_CONFIRM, sizeof(uiconfirm_t)); - - errorChain(assetLocaleGetString( - &LOCALE.entry->data.locale, - "ui.confirm.confirm", - 0, - UI_CONFIRM.confirmLabel, - UI_CONFIRM_LABEL_MAX - )); - errorChain(assetLocaleGetString( - &LOCALE.entry->data.locale, - "ui.confirm.cancel", - 0, - UI_CONFIRM.cancelLabel, - UI_CONFIRM_LABEL_MAX - )); - - MENU_BEGIN( - &UI_CONFIRM.menu, UI_CONFIRM.items, uiConfirmSelected, uiConfirmClosed, NULL - ); - MENU_BUTTON(UI_CONFIRM.confirmLabel); - MENU_BUTTON(UI_CONFIRM.cancelLabel); - - MENU_END(UI_CONFIRM.items, menuIndex); - - errorOk(); -} - -errorret_t uiConfirmDraw(void) { - if(!uiMenuIsActive(&UI_CONFIRM.menu)) errorOk(); - - spritebatchsprite_t backdropSprite = { - .min = { 0.0f, 0.0f, 0.0f }, - .max = { (float_t)SCREEN.width, (float_t)SCREEN.height, 0.0f }, - .uvMin = { 0.0f, 0.0f }, - .uvMax = { 1.0f, 1.0f } - }; - shadermaterial_t backdropMaterial = { - .unlit = { - .color = UI_CONFIRM_BACKDROP_COLOR, - .texture = &TEXTURE_WHITE - } - }; - errorChain( - spriteBatchBuffer(&backdropSprite, 1, &SHADER_UNLIT, backdropMaterial) - ); - errorChain(spriteBatchFlush()); - - int32_t textW, textH; - textMeasure(UI_CONFIRM.text, &FONT_DEFAULT, &textW, &textH); - - float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight; - float_t width = mathMax( - (float_t)textW + (UI_FRAME_START_X * 2), UI_CONFIRM_MIN_WIDTH - ); - float_t height = (UI_FRAME_START_Y * 2) + rowHeight + UI_FRAME_PADDING_Y + - rowHeight; - float_t x = (float_t)SCREEN.scanX + ((float_t)SCREEN.scanWidth - width) * 0.5f; - float_t y = (float_t)SCREEN.scanY + ((float_t)SCREEN.scanHeight - height) * 0.5f; - - errorChain(uiFrameDraw(x, y, width, height)); - - float_t contentX = x + UI_FRAME_START_X; - float_t contentY = y + UI_FRAME_START_Y; - float_t contentWidth = width - (UI_FRAME_START_X * 2); - - errorChain(textDraw(contentX, contentY, UI_CONFIRM.text, COLOR_WHITE, &FONT_DEFAULT)); - - float_t buttonsY = contentY + rowHeight + UI_FRAME_PADDING_Y; - errorChain(uiMenuDraw(&UI_CONFIRM.menu, contentX, buttonsY, contentWidth, rowHeight)); - - errorChain(spriteBatchFlush()); errorOk(); } bool_t uiConfirmIsOpen(void) { - return uiMenuIsActive(&UI_CONFIRM.menu); + return uiModalIsOpen(); } bool_t uiConfirmGetResult(void) { @@ -129,15 +41,22 @@ void uiConfirmOpen( void *user ) { assertNotNull(question, "Question cannot be NULL"); - stringCopy(UI_CONFIRM.text, question, UI_CONFIRM_TEXT_MAX); + UI_CONFIRM.callback = callback; - UI_CONFIRM.user = user; UI_CONFIRM.result = false; - uiMenuOpen(&UI_CONFIRM.menu); + + const char_t *options[] = { + "ui.confirm.confirm", + "ui.confirm.cancel" + }; + uiModalOpen( + NULL, question, options, sizeof(options) / sizeof(options[0]), + uiConfirmModalCallback, NULL, user + ); } void uiConfirmClose(void) { - uiMenuClose(&UI_CONFIRM.menu); + uiModalClose(NULL); } errorret_t uiConfirmDispose(void) { diff --git a/src/dusk/ui/frame/uiconfirm.h b/src/dusk/ui/frame/uiconfirm.h index 429d9654..398aff14 100644 --- a/src/dusk/ui/frame/uiconfirm.h +++ b/src/dusk/ui/frame/uiconfirm.h @@ -7,14 +7,6 @@ #pragma once #include "error/error.h" -#include "ui/widget/uimenu.h" - -#define UI_CONFIRM_TEXT_MAX 256 -#define UI_CONFIRM_MIN_WIDTH 160.0f -#define UI_CONFIRM_INDEX_CONFIRM 0 -#define UI_CONFIRM_INDEX_CANCEL 1 -#define UI_CONFIRM_ITEM_COUNT 2 -#define UI_CONFIRM_LABEL_MAX 32 /** * Callback invoked once a confirm dialog is dismissed. @@ -26,14 +18,8 @@ typedef void (*uiconfirmcallback_t)(const bool_t result, void *user); typedef struct { - char_t text[UI_CONFIRM_TEXT_MAX]; - uimenu_t menu; - uimenuitem_t items[UI_CONFIRM_ITEM_COUNT]; uiconfirmcallback_t callback; - void *user; bool_t result; - char_t confirmLabel[UI_CONFIRM_LABEL_MAX]; - char_t cancelLabel[UI_CONFIRM_LABEL_MAX]; } uiconfirm_t; extern uiconfirm_t UI_CONFIRM; @@ -45,15 +31,6 @@ extern uiconfirm_t UI_CONFIRM; */ errorret_t uiConfirmInit(void); -/** - * Draws the confirm dialog: a semi-transparent black backdrop covering - * the whole screen, then its own centered frame with the question text - * and Confirm/Cancel buttons. No-op when not open. - * - * @return Any error that occurs. - */ -errorret_t uiConfirmDraw(void); - /** * Returns true when the confirm dialog is currently open. * @@ -69,11 +46,13 @@ bool_t uiConfirmIsOpen(void); bool_t uiConfirmGetResult(void); /** - * Opens the confirm dialog with the given question text. callback is - * invoked exactly once with the result, whether the dialog was - * dismissed by selecting a button or by pressing cancel/back. + * Opens a confirm dialog, backed by the shared uimodal_t, with the given + * question text and Confirm/Cancel buttons. callback is invoked exactly + * once with the result, whether the dialog was dismissed by selecting a + * button or by pressing cancel/back. * - * @param question Display text; copied internally, safe to be transient. + * @param question Display text, or a locale message ID; copied + * internally by uimodal, safe to be transient. * @param callback Called with the result once the dialog closes. May be * NULL. * @param user Arbitrary pointer passed through to callback. diff --git a/src/dusk/ui/uielementlist.c b/src/dusk/ui/uielementlist.c index 860752fa..8a03db6e 100644 --- a/src/dusk/ui/uielementlist.c +++ b/src/dusk/ui/uielementlist.c @@ -86,7 +86,6 @@ uielement_t UI_ELEMENTS[] = { // =========================================================================== { .init = uiConfirmInit, - .draw = uiConfirmDraw, .dispose = uiConfirmDispose }, { diff --git a/src/dusk/ui/widget/uimodal.c b/src/dusk/ui/widget/uimodal.c index d070a347..97a1c62c 100644 --- a/src/dusk/ui/widget/uimodal.c +++ b/src/dusk/ui/widget/uimodal.c @@ -85,7 +85,8 @@ errorret_t uiModalDraw(void) { ); float_t width = contentWidth + (UI_FRAME_START_X * 2); float_t height = (UI_FRAME_START_Y * 2) - + (float_t)UI_MODAL.titleLabel.height + UI_FRAME_PADDING_Y + + (UI_MODAL.hasTitle ? + (float_t)UI_MODAL.titleLabel.height + UI_FRAME_PADDING_Y : 0.0f) + (float_t)UI_MODAL.messageLabel.height + (hasOptions ? UI_FRAME_PADDING_Y + rowHeight : 0.0f); @@ -99,12 +100,16 @@ errorret_t uiModalDraw(void) { float_t contentX = x + UI_FRAME_START_X; float_t contentY = y + UI_FRAME_START_Y; - uiLabelSetX(&UI_MODAL.titleLabel, contentX); - uiLabelSetY(&UI_MODAL.titleLabel, contentY); - errorChain(uiLabelRender(&UI_MODAL.titleLabel, COLOR_WHITE)); + float_t messageY = contentY; + if(UI_MODAL.hasTitle) { + uiLabelSetX(&UI_MODAL.titleLabel, contentX); + uiLabelSetY(&UI_MODAL.titleLabel, contentY); + errorChain(uiLabelRender(&UI_MODAL.titleLabel, COLOR_WHITE)); + + messageY = contentY + (float_t)UI_MODAL.titleLabel.height + + UI_FRAME_PADDING_Y; + } - float_t messageY = contentY + (float_t)UI_MODAL.titleLabel.height + - UI_FRAME_PADDING_Y; uiLabelSetX(&UI_MODAL.messageLabel, contentX); uiLabelSetY(&UI_MODAL.messageLabel, messageY); errorChain(uiLabelRender(&UI_MODAL.messageLabel, COLOR_WHITE)); @@ -152,7 +157,6 @@ void uiModalOpen( uimodalopenedcallback_t onOpen, void *user ) { - assertNotNull(title, "Title cannot be NULL"); assertNotNull(message, "Message cannot be NULL"); assertTrue( options != NULL || optionCount == 0, @@ -165,8 +169,13 @@ void uiModalOpen( float_t maxContentWidth = ((float_t)SCREEN.scanWidth * UI_MODAL_MAX_WIDTH_RATIO) - (UI_FRAME_START_X * 2.0f); - uiModalLocalize(title, UI_MODAL.titleText, UI_MODAL_TITLE_TEXT_MAX); - textWrap(UI_MODAL.titleText, &FONT_DEFAULT, maxContentWidth); + UI_MODAL.hasTitle = title != NULL; + if(UI_MODAL.hasTitle) { + uiModalLocalize(title, UI_MODAL.titleText, UI_MODAL_TITLE_TEXT_MAX); + textWrap(UI_MODAL.titleText, &FONT_DEFAULT, maxContentWidth); + } else { + UI_MODAL.titleText[0] = '\0'; + } UI_MODAL.titleLabel.dirty = true; uiLabelRebuffer(&UI_MODAL.titleLabel); diff --git a/src/dusk/ui/widget/uimodal.h b/src/dusk/ui/widget/uimodal.h index 49c51d0f..0434ac86 100644 --- a/src/dusk/ui/widget/uimodal.h +++ b/src/dusk/ui/widget/uimodal.h @@ -66,6 +66,7 @@ typedef struct { void *user; uint8_t result; bool_t open; + bool_t hasTitle; } uimodal_t; extern uimodal_t UI_MODAL; @@ -111,7 +112,8 @@ uint8_t uiModalGetResult(void); * verbatim. See uiModalLocalize. * * @param title Display title, or a locale message ID; copied - * internally, safe to be transient. + * internally, safe to be transient. May be NULL for a dialog with no + * title row. * @param message Display message, or a locale message ID; copied * internally, safe to be transient. * @param options Array of option label strings/locale message IDs;