diff --git a/src/window/hotkey_config.c b/src/window/hotkey_config.c index 4b9f124e73..cacc37cc97 100644 --- a/src/window/hotkey_config.c +++ b/src/window/hotkey_config.c @@ -20,6 +20,7 @@ #include "window/config.h" #include "window/hotkey_editor.h" #include "window/plain_message_dialog.h" +#include "window/popup_dialog.h" #define TR_NONE -1 #define GROUP_BUILDINGS 28 @@ -232,6 +233,15 @@ static struct { unsigned int focus_button; unsigned int bottom_focus_button; hotkey_mapping mappings[HOTKEY_MAX_ITEMS][2]; + struct { + int is_pending; + hotkey_action from_action; + int from_index; + hotkey_action to_action; + int to_index; + key_type key; + key_modifier_type modifiers; + } pending_remap; } data; int get_position_for_widget(translation_key key) @@ -247,6 +257,7 @@ int get_position_for_widget(translation_key key) static void init(int position) { scrollbar_init(&scrollbar, position, sizeof(hotkey_widgets) / sizeof(hotkey_widget)); + data.pending_remap.is_pending = 0; for (int i = 0; i < HOTKEY_MAX_ITEMS; i++) { hotkey_mapping empty = { KEY_TYPE_NONE, KEY_MOD_NONE, i }; @@ -380,6 +391,24 @@ static const uint8_t *hotkey_action_name_for(hotkey_action action) return name; } +static void hotkey_remap_confirmation(int accepted, int checked) +{ + if (!data.pending_remap.is_pending) { + return; + } + + if (accepted) { + data.mappings[data.pending_remap.from_action][data.pending_remap.from_index].key = KEY_TYPE_NONE; + data.mappings[data.pending_remap.from_action][data.pending_remap.from_index].modifiers = KEY_MOD_NONE; + + data.mappings[data.pending_remap.to_action][data.pending_remap.to_index].key = data.pending_remap.key; + data.mappings[data.pending_remap.to_action][data.pending_remap.to_index].modifiers = data.pending_remap.modifiers; + } + + data.pending_remap.is_pending = 0; + window_invalidate(); +} + static void set_hotkey(hotkey_action action, int index, key_type key, key_modifier_type modifiers) { int is_duplicate_hotkey = 0; @@ -394,9 +423,18 @@ static void set_hotkey(hotkey_action action, int index, key_type key, key_modifi // "Fire overlay" already has hotkey "F" and user tries set same hotkey "F" again to "Fire overlay" // we must skip show warning window for better user experience if (!(test_action == action && test_index == index)) { - window_plain_message_dialog_show_with_extra( + data.pending_remap.is_pending = 1; + data.pending_remap.from_action = test_action; + data.pending_remap.from_index = test_index; + data.pending_remap.to_action = action; + data.pending_remap.to_index = index; + data.pending_remap.key = key; + data.pending_remap.modifiers = modifiers; + + window_popup_dialog_show_confirmation_with_extra( TR_HOTKEY_DUPLICATE_TITLE, TR_HOTKEY_DUPLICATE_MESSAGE, - hotkey_action_name_for(test_action), 0); + hotkey_action_name_for(test_action), hotkey_action_name_for(action), + hotkey_remap_confirmation); } break; } diff --git a/src/window/popup_dialog.c b/src/window/popup_dialog.c index 6283b08c4a..b6d698afac 100644 --- a/src/window/popup_dialog.c +++ b/src/window/popup_dialog.c @@ -19,6 +19,7 @@ #define PROCEED_GROUP 43 #define PROCEED_TEXT 5 #define CHECKBOX_CHECK_SIZE 20 +#define CONFIRMATION_WITH_EXTRA_MAX_LENGTH 512 static void button_checkbox(const generic_button *button); static void button_ok(int param1, int param2); @@ -32,6 +33,8 @@ static image_button buttons[] = { static generic_button checkbox = { 160, 180, 360, 20, button_checkbox }; +static uint8_t confirmation_with_extra_text[CONFIRMATION_WITH_EXTRA_MAX_LENGTH]; + static struct { int ok_clicked; void (*close_func)(int accepted, int checked); @@ -172,3 +175,50 @@ void window_popup_dialog_show_confirmation(const uint8_t *custom_title, const ui window_show(&window); } } + +void window_popup_dialog_show_confirmation_with_extra(translation_key title, translation_key message, + const uint8_t *extra, const uint8_t *extra2, void (*close_func)(int accepted, int checked)) +{ + const uint8_t *title_text = translation_for(title); + const uint8_t *message_text = translation_for(message); + + if (!extra && !extra2) { + window_popup_dialog_show_confirmation(title_text, message_text, 0, close_func); + return; + } + + uint8_t *cursor = confirmation_with_extra_text; + int remaining = CONFIRMATION_WITH_EXTRA_MAX_LENGTH; + + cursor = string_copy(message_text, cursor, remaining); + remaining = CONFIRMATION_WITH_EXTRA_MAX_LENGTH - (cursor - confirmation_with_extra_text); + + if (extra) { + if (remaining > 1) { + *cursor = '\n'; + cursor++; + *cursor = 0; + remaining--; + } + cursor = string_copy(extra, cursor, remaining); + remaining = CONFIRMATION_WITH_EXTRA_MAX_LENGTH - (cursor - confirmation_with_extra_text); + } + + if (extra2) { + if (!extra && remaining > 1) { + *cursor = '\n'; + cursor++; + *cursor = 0; + remaining--; + } + if (remaining > 1) { + *cursor = '\n'; + cursor++; + *cursor = 0; + remaining--; + } + string_copy(extra2, cursor, remaining); + } + + window_popup_dialog_show_confirmation(title_text, confirmation_with_extra_text, 0, close_func); +} diff --git a/src/window/popup_dialog.h b/src/window/popup_dialog.h index fdb866a3fb..6c21f3aa0c 100644 --- a/src/window/popup_dialog.h +++ b/src/window/popup_dialog.h @@ -1,6 +1,8 @@ #ifndef WINDOW_POPUP_DIALOG_H #define WINDOW_POPUP_DIALOG_H +#include "translation/translation.h" + #include typedef enum { @@ -24,4 +26,7 @@ void window_popup_dialog_show(popup_dialog_type type, void window_popup_dialog_show_confirmation(const uint8_t *custom_title, const uint8_t *custom_text, const uint8_t *checkbox_text, void (*close_func)(int accepted, int checked)); +void window_popup_dialog_show_confirmation_with_extra(translation_key title, translation_key message, + const uint8_t *extra, const uint8_t *extra2, void (*close_func)(int accepted, int checked)); + #endif // WINDOW_POPUP_DIALOG_H