Rebuild uiconfirm on top of uimodal, add quit confirmation
uiconfirm no longer duplicates its own backdrop/frame/text/menu drawing - it now just opens the shared uimodal_t with a Confirm/Cancel option pair and translates the result back to a bool. uimodal itself gains an optional title (NULL skips the title row entirely) so a title-less confirm dialog doesn't reserve blank space. Main menu's Quit option now opens a confirm dialog instead of exiting immediately. Drops es_MX.po/jp_JP.po locale files. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ msgstr "Try again"
|
|||||||
msgid "initial.no_device.continue"
|
msgid "initial.no_device.continue"
|
||||||
msgstr "Continue without saving"
|
msgstr "Continue without saving"
|
||||||
|
|
||||||
|
|
||||||
# Main Menu Scene
|
# Main Menu Scene
|
||||||
msgid "main_menu.new_game"
|
msgid "main_menu.new_game"
|
||||||
msgstr "New Game"
|
msgstr "New Game"
|
||||||
@@ -37,6 +38,19 @@ msgstr "Options"
|
|||||||
msgid "main_menu.quit"
|
msgid "main_menu.quit"
|
||||||
msgstr "Quit Game"
|
msgstr "Quit Game"
|
||||||
|
|
||||||
|
msgid "main_menu.quit_confirm"
|
||||||
|
msgstr "Are you sure you want to quit?"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#: ui/menu.c:10
|
#: ui/menu.c:10
|
||||||
msgid "ui.title"
|
msgid "ui.title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -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"
|
|
||||||
@@ -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 "リンゴ"
|
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "locale/localemanager.h"
|
#include "locale/localemanager.h"
|
||||||
#include "asset/loader/locale/assetlocaleloader.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_NEW_GAME 0
|
||||||
#define UI_MAIN_MENU_INDEX_LOAD_GAME 1
|
#define UI_MAIN_MENU_INDEX_LOAD_GAME 1
|
||||||
@@ -23,15 +24,19 @@
|
|||||||
|
|
||||||
uimainmenu_t UI_MAIN_MENU;
|
uimainmenu_t UI_MAIN_MENU;
|
||||||
|
|
||||||
|
void uiMainMenuQuitConfirmed(const bool_t result, void *user) {
|
||||||
|
if(result) ENGINE.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
void uiMainMenuSelected(
|
void uiMainMenuSelected(
|
||||||
const uimenu_t *menu,
|
const uimenu_t *menu,
|
||||||
const uint8_t index,
|
const uint8_t index,
|
||||||
const uimenuitem_t *item
|
const uimenuitem_t *item
|
||||||
) {
|
) {
|
||||||
uiMenuClose(&UI_MAIN_MENU.menu);
|
|
||||||
|
|
||||||
switch(index) {
|
switch(index) {
|
||||||
case UI_MAIN_MENU_INDEX_NEW_GAME:
|
case UI_MAIN_MENU_INDEX_NEW_GAME:
|
||||||
|
uiMenuClose(&UI_MAIN_MENU.menu);
|
||||||
testBattleStart();
|
testBattleStart();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -44,7 +49,7 @@ void uiMainMenuSelected(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case UI_MAIN_MENU_INDEX_QUIT:
|
case UI_MAIN_MENU_INDEX_QUIT:
|
||||||
ENGINE.running = false;
|
uiConfirmOpen("main_menu.quit_confirm", uiMainMenuQuitConfirmed, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -6,117 +6,29 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uiconfirm.h"
|
#include "uiconfirm.h"
|
||||||
#include "ui/widget/uiframe.h"
|
#include "ui/widget/uimodal.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.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;
|
uiconfirm_t UI_CONFIRM;
|
||||||
|
|
||||||
void uiConfirmSelected(
|
void uiConfirmModalCallback(const uint8_t optionIndex, void *user) {
|
||||||
const uimenu_t *menu,
|
UI_CONFIRM.result = optionIndex == UI_CONFIRM_INDEX_CONFIRM;
|
||||||
const uint8_t index,
|
|
||||||
const uimenuitem_t *item
|
|
||||||
) {
|
|
||||||
UI_CONFIRM.result = index == UI_CONFIRM_INDEX_CONFIRM;
|
|
||||||
uiConfirmClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiConfirmClosed(const uimenu_t *menu) {
|
|
||||||
if(UI_CONFIRM.callback != NULL) {
|
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) {
|
errorret_t uiConfirmInit(void) {
|
||||||
memoryZero(&UI_CONFIRM, sizeof(uiconfirm_t));
|
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();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t uiConfirmIsOpen(void) {
|
bool_t uiConfirmIsOpen(void) {
|
||||||
return uiMenuIsActive(&UI_CONFIRM.menu);
|
return uiModalIsOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t uiConfirmGetResult(void) {
|
bool_t uiConfirmGetResult(void) {
|
||||||
@@ -129,15 +41,22 @@ void uiConfirmOpen(
|
|||||||
void *user
|
void *user
|
||||||
) {
|
) {
|
||||||
assertNotNull(question, "Question cannot be NULL");
|
assertNotNull(question, "Question cannot be NULL");
|
||||||
stringCopy(UI_CONFIRM.text, question, UI_CONFIRM_TEXT_MAX);
|
|
||||||
UI_CONFIRM.callback = callback;
|
UI_CONFIRM.callback = callback;
|
||||||
UI_CONFIRM.user = user;
|
|
||||||
UI_CONFIRM.result = false;
|
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) {
|
void uiConfirmClose(void) {
|
||||||
uiMenuClose(&UI_CONFIRM.menu);
|
uiModalClose(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t uiConfirmDispose(void) {
|
errorret_t uiConfirmDispose(void) {
|
||||||
|
|||||||
@@ -7,14 +7,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#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.
|
* Callback invoked once a confirm dialog is dismissed.
|
||||||
@@ -26,14 +18,8 @@
|
|||||||
typedef void (*uiconfirmcallback_t)(const bool_t result, void *user);
|
typedef void (*uiconfirmcallback_t)(const bool_t result, void *user);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char_t text[UI_CONFIRM_TEXT_MAX];
|
|
||||||
uimenu_t menu;
|
|
||||||
uimenuitem_t items[UI_CONFIRM_ITEM_COUNT];
|
|
||||||
uiconfirmcallback_t callback;
|
uiconfirmcallback_t callback;
|
||||||
void *user;
|
|
||||||
bool_t result;
|
bool_t result;
|
||||||
char_t confirmLabel[UI_CONFIRM_LABEL_MAX];
|
|
||||||
char_t cancelLabel[UI_CONFIRM_LABEL_MAX];
|
|
||||||
} uiconfirm_t;
|
} uiconfirm_t;
|
||||||
|
|
||||||
extern uiconfirm_t UI_CONFIRM;
|
extern uiconfirm_t UI_CONFIRM;
|
||||||
@@ -45,15 +31,6 @@ extern uiconfirm_t UI_CONFIRM;
|
|||||||
*/
|
*/
|
||||||
errorret_t uiConfirmInit(void);
|
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.
|
* Returns true when the confirm dialog is currently open.
|
||||||
*
|
*
|
||||||
@@ -69,11 +46,13 @@ bool_t uiConfirmIsOpen(void);
|
|||||||
bool_t uiConfirmGetResult(void);
|
bool_t uiConfirmGetResult(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the confirm dialog with the given question text. callback is
|
* Opens a confirm dialog, backed by the shared uimodal_t, with the given
|
||||||
* invoked exactly once with the result, whether the dialog was
|
* question text and Confirm/Cancel buttons. callback is invoked exactly
|
||||||
* dismissed by selecting a button or by pressing cancel/back.
|
* 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
|
* @param callback Called with the result once the dialog closes. May be
|
||||||
* NULL.
|
* NULL.
|
||||||
* @param user Arbitrary pointer passed through to callback.
|
* @param user Arbitrary pointer passed through to callback.
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ uielement_t UI_ELEMENTS[] = {
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
{
|
{
|
||||||
.init = uiConfirmInit,
|
.init = uiConfirmInit,
|
||||||
.draw = uiConfirmDraw,
|
|
||||||
.dispose = uiConfirmDispose
|
.dispose = uiConfirmDispose
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ errorret_t uiModalDraw(void) {
|
|||||||
);
|
);
|
||||||
float_t width = contentWidth + (UI_FRAME_START_X * 2);
|
float_t width = contentWidth + (UI_FRAME_START_X * 2);
|
||||||
float_t height = (UI_FRAME_START_Y * 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
|
+ (float_t)UI_MODAL.messageLabel.height
|
||||||
+ (hasOptions ? UI_FRAME_PADDING_Y + rowHeight : 0.0f);
|
+ (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 contentX = x + UI_FRAME_START_X;
|
||||||
float_t contentY = y + UI_FRAME_START_Y;
|
float_t contentY = y + UI_FRAME_START_Y;
|
||||||
|
|
||||||
uiLabelSetX(&UI_MODAL.titleLabel, contentX);
|
float_t messageY = contentY;
|
||||||
uiLabelSetY(&UI_MODAL.titleLabel, contentY);
|
if(UI_MODAL.hasTitle) {
|
||||||
errorChain(uiLabelRender(&UI_MODAL.titleLabel, COLOR_WHITE));
|
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);
|
uiLabelSetX(&UI_MODAL.messageLabel, contentX);
|
||||||
uiLabelSetY(&UI_MODAL.messageLabel, messageY);
|
uiLabelSetY(&UI_MODAL.messageLabel, messageY);
|
||||||
errorChain(uiLabelRender(&UI_MODAL.messageLabel, COLOR_WHITE));
|
errorChain(uiLabelRender(&UI_MODAL.messageLabel, COLOR_WHITE));
|
||||||
@@ -152,7 +157,6 @@ void uiModalOpen(
|
|||||||
uimodalopenedcallback_t onOpen,
|
uimodalopenedcallback_t onOpen,
|
||||||
void *user
|
void *user
|
||||||
) {
|
) {
|
||||||
assertNotNull(title, "Title cannot be NULL");
|
|
||||||
assertNotNull(message, "Message cannot be NULL");
|
assertNotNull(message, "Message cannot be NULL");
|
||||||
assertTrue(
|
assertTrue(
|
||||||
options != NULL || optionCount == 0,
|
options != NULL || optionCount == 0,
|
||||||
@@ -165,8 +169,13 @@ void uiModalOpen(
|
|||||||
float_t maxContentWidth = ((float_t)SCREEN.scanWidth * UI_MODAL_MAX_WIDTH_RATIO)
|
float_t maxContentWidth = ((float_t)SCREEN.scanWidth * UI_MODAL_MAX_WIDTH_RATIO)
|
||||||
- (UI_FRAME_START_X * 2.0f);
|
- (UI_FRAME_START_X * 2.0f);
|
||||||
|
|
||||||
uiModalLocalize(title, UI_MODAL.titleText, UI_MODAL_TITLE_TEXT_MAX);
|
UI_MODAL.hasTitle = title != NULL;
|
||||||
textWrap(UI_MODAL.titleText, &FONT_DEFAULT, maxContentWidth);
|
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;
|
UI_MODAL.titleLabel.dirty = true;
|
||||||
uiLabelRebuffer(&UI_MODAL.titleLabel);
|
uiLabelRebuffer(&UI_MODAL.titleLabel);
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ typedef struct {
|
|||||||
void *user;
|
void *user;
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
bool_t open;
|
bool_t open;
|
||||||
|
bool_t hasTitle;
|
||||||
} uimodal_t;
|
} uimodal_t;
|
||||||
|
|
||||||
extern uimodal_t UI_MODAL;
|
extern uimodal_t UI_MODAL;
|
||||||
@@ -111,7 +112,8 @@ uint8_t uiModalGetResult(void);
|
|||||||
* verbatim. See uiModalLocalize.
|
* verbatim. See uiModalLocalize.
|
||||||
*
|
*
|
||||||
* @param title Display title, or a locale message ID; copied
|
* @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
|
* @param message Display message, or a locale message ID; copied
|
||||||
* internally, safe to be transient.
|
* internally, safe to be transient.
|
||||||
* @param options Array of option label strings/locale message IDs;
|
* @param options Array of option label strings/locale message IDs;
|
||||||
|
|||||||
Reference in New Issue
Block a user