From ff290775814af246a4e4713a35352a8d835315e8 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:50:43 +0000 Subject: [PATCH 01/18] This is really confusing :c --- src/do_turn.cpp | 5 +- src/handle_action.cpp | 6 +- src/help.cpp | 248 ++++++++++++++++-------------------------- src/help.h | 39 +++++-- src/main_menu.cpp | 6 +- 5 files changed, 136 insertions(+), 168 deletions(-) diff --git a/src/do_turn.cpp b/src/do_turn.cpp index e2cef4622e979..26f27a560a3a5 100644 --- a/src/do_turn.cpp +++ b/src/do_turn.cpp @@ -246,8 +246,9 @@ void handle_key_blocking_activity() u.disp_info( true ); } else if( action == "messages" ) { Messages::display_messages(); - } else if( action == "help" ) { - get_help().display_help(); + } else if( action == "DISPLAY_HELP" ) { + help_window hw; + hw.show(); } else if( action != "HELP_KEYBINDINGS" ) { refresh = false; } diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 56b82c4c5f9c0..0a4d968b53943 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -2887,9 +2887,11 @@ bool game::do_regular_action( action_id &act, avatar &player_character, Messages::display_messages(); break; - case ACTION_HELP: - get_help().display_help(); + case ACTION_HELP: { + help_window hw; + hw.show(); break; + } case ACTION_OPTIONS: get_options().show( true ); diff --git a/src/help.cpp b/src/help.cpp index 3812e32f19de9..1d9791fd621d1 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -9,6 +9,11 @@ #include #include +#include "cata_imgui.h" +#include "input_context.h" +#include "imgui/imgui.h" +#include "output.h" + #include "action.h" #include "catacharset.h" #include "color.h" @@ -24,6 +29,14 @@ #include "translations.h" #include "ui_manager.h" +// Imgui planning +//////////////////////////////////////////////////////////////////////// +// Tabular full screen menu +// 1 Tab per mod (overflow to an additional tab if more than 52 entries) +// General read/unread functionality +// Short desc for each category? +// Handling for tiny screens (mobile) + class JsonObject; help &get_help() @@ -70,7 +83,7 @@ void help::load_object( const JsonObject &jo, const std::string &src ) } } -std::string help::get_dir_grid() +std::string help_window::get_dir_grid() { static const std::array movearray = {{ ACTION_MOVE_FORTH_LEFT, ACTION_MOVE_FORTH, ACTION_MOVE_FORTH_RIGHT, @@ -101,49 +114,7 @@ std::string help::get_dir_grid() return movement; } -std::map> help::draw_menu( const catacurses::window &win, - int selected, std::map &hotkeys ) const -{ - std::map> opt_map; - - werase( win ); - // NOLINTNEXTLINE(cata-use-named-point-constants) - int y = fold_and_print( win, point( 1, 0 ), getmaxx( win ) - 2, c_white, - _( "Please press one of the following for help on that topic:\n" - "Press ESC to return to the game." ) ) + 1; - - size_t half_size = help_texts.size() / 2 + 1; - int second_column = divide_round_up( getmaxx( win ), 2 ); - size_t i = 0; - for( const auto &text : help_texts ) { - std::string cat_name; - auto hotkey_it = hotkeys.find( text.first ); - if( hotkey_it != hotkeys.end() ) { - cat_name = colorize( hotkey_it->second.short_description(), - selected == text.first ? hilite( c_light_blue ) : c_light_blue ); - cat_name += ": "; - } - cat_name += text.second.first.translated(); - const int cat_width = utf8_width( remove_color_tags( cat_name ) ); - if( i < half_size ) { - second_column = std::max( second_column, cat_width + 4 ); - } - - const point sc_start( i < half_size ? 1 : second_column, y + i % half_size ); - fold_and_print( win, sc_start, getmaxx( win ) - 2, - selected == text.first ? hilite( c_white ) : c_white, cat_name ); - ++i; - - opt_map.emplace( text.first, - inclusive_rectangle( sc_start, sc_start + point( cat_width - 1, 0 ) ) ); - } - - wnoutrefresh( win ); - - return opt_map; -} - -std::string help::get_note_colors() +std::string help_window::get_note_colors() { std::string text = _( "Note colors: " ); for( const auto &color_pair : get_note_color_names() ) { @@ -157,136 +128,105 @@ std::string help::get_note_colors() return text; } -void help::display_help() const +help_window::help_window() : cataimgui::window( "help", + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoNavInputs ) { - catacurses::window w_help_border; - catacurses::window w_help; - - ui_adaptor ui; - const auto init_windows = [&]( ui_adaptor & ui ) { - w_help_border = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, - point( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0, - TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ) ); - w_help = catacurses::newwin( FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 2, - point( 1 + static_cast( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 ), - 1 + static_cast( TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ) ) ); - ui.position_from_window( w_help_border ); - }; - init_windows( ui ); - ui.on_screen_resize( init_windows ); - input_context ctxt( "DISPLAY_HELP", keyboard_mode::keychar ); ctxt.register_cardinal(); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); - // for mouse selection + //ctxt.register_action( "NEXT_TAB" ); + //ctxt.register_action( "PREV_TAB" ); + // Mouse selection ctxt.register_action( "SELECT" ); ctxt.register_action( "MOUSE_MOVE" ); - // for the menu shortcuts + // Generated shortcuts ctxt.register_action( "ANY_INPUT" ); - - std::string action; - std::map> opt_map; - int sel = -1; - const hotkey_queue &hkq = hotkey_queue::alphabets(); input_event next_hotkey = ctxt.first_unassigned_hotkey( hkq ); - std::map hotkeys; - for( const auto &text : help_texts ) { + for( const auto &text : data.help_texts ) { hotkeys.emplace( text.first, next_hotkey ); next_hotkey = ctxt.next_unassigned_hotkey( hkq, next_hotkey ); } +} - ui.on_redraw( [&]( const ui_adaptor & ) { - draw_border( w_help_border, BORDER_COLOR, _( "Help" ) ); - wnoutrefresh( w_help_border ); - opt_map = draw_menu( w_help, sel, hotkeys ); - } ); - - do { - ui_manager::redraw(); - - sel = -1; - action = ctxt.handle_input(); - input_event input = ctxt.get_raw_input(); - - // Mouse selection - if( action == "MOUSE_MOVE" || action == "SELECT" ) { - std::optional coord = ctxt.get_coordinates_text( w_help ); - if( !!coord ) { - int cnt = run_for_point_in( opt_map, *coord, - [&sel]( const std::pair> &p ) { - sel = p.first; - } ); - if( cnt > 0 && action == "SELECT" ) { - auto iter = hotkeys.find( sel ); - if( iter != hotkeys.end() ) { - input = iter->second; - action = "CONFIRM"; - } - } - } +void help_window::draw_controls() +{ + //if( ImGui::BeginTabBar( "idk" ) ) { + // ImGui::EndTabBar(); + //} + mouse_selected_option = -1; + size_t ind = 0; + for( const auto &text : data.help_texts ) { + std::string cat_name; + auto hotkey_it = hotkeys.find( text.first ); + if( hotkey_it != hotkeys.end() ) { + cat_name = hotkey_it->second.short_description(); + cat_name += ": "; } + cat_name += text.second.first.translated(); + ImGui::Button( remove_color_tags( cat_name ).c_str() ); + if( ImGui::IsItemHovered() ) { + mouse_selected_option = ind; + } + if( keyboard_selected_option != last_keyboard_selected_option && + keyboard_selected_option == short( ind ) && ImGui::IsWindowFocused() ) { + ImGui::SetKeyboardFocusHere( -1 ); + } + ind++; + } +} - for( const auto &hotkey_entry : hotkeys ) { - auto help_text_it = help_texts.find( hotkey_entry.first ); - if( help_text_it == help_texts.end() ) { - continue; - } - if( input == hotkey_entry.second ) { - std::vector i18n_help_texts; - i18n_help_texts.reserve( help_text_it->second.second.size() ); - std::transform( help_text_it->second.second.begin(), help_text_it->second.second.end(), - std::back_inserter( i18n_help_texts ), [&]( const translation & line ) { - std::string line_proc = line.translated(); - if( line_proc == "" ) { - line_proc = get_note_colors(); - } else if( line_proc == "" ) { - line_proc = get_dir_grid(); - } - size_t pos = line_proc.find( "", pos, 1 ); - - std::string action = line_proc.substr( pos + 7, pos2 - pos - 7 ); - std::string replace = "" + - press_x( look_up_action( action ), "", "" ) + ""; - - if( replace.empty() ) { - debugmsg( "Help json: Unknown action: %s", action ); - } else { - line_proc = string_replace( - line_proc, "", replace ); - } - - pos = line_proc.find( " ¶graphs ) +{ + cataimgui::draw_colored_text( category_name.translated() ); + for( const translation ¶graph : paragraphs ) { + ImGui::NewLine(); + ImGui::NewLine(); + cataimgui::draw_colored_text( paragraph.translated() ); + } + mark_resized(); + while( true ) { + ui_manager::redraw_invalidated(); + const std::string action = ctxt.handle_input( 50 ); + if( action == "CONFIRM" || action == "QUIT" ) { + return; + } + } +} - ui.on_screen_resize( init_windows ); - } - action = "CONFIRM"; - break; +cataimgui::bounds help_window::get_bounds() +{ + return bounds; +} +void help_window::show() +{ + size_t selected = 0; + while( true ) { + ui_manager::redraw_invalidated(); + std::string action = ctxt.handle_input( 50 ); + //const input_event event = ctxt.get_raw_input(); + //if( action == "NEXT_TAB" ) { + // switch_target = cur_target; + // ++switch_target; + //} else if( action == "PREV_TAB" ) { + // switch_target = cur_target; + // --switch_target; + //} else + if( action == "SELECT" && mouse_selected_option != -1 ) { + action = "CONFIRM"; + selected = size_t( mouse_selected_option ); + } + if( action == "CONFIRM" ) { + if( auto it = data.help_texts.find( selected ); it != data.help_texts.end() ) { + draw_category( it->second.first, it->second.second ); } + } else if( action == "QUIT" ) { + return; } - } while( action != "QUIT" ); + } } std::string get_hint() diff --git a/src/help.h b/src/help.h index e5ed2b6b8e56d..d685b8905bef4 100644 --- a/src/help.h +++ b/src/help.h @@ -8,8 +8,10 @@ #include #include -#include "cuboid_rectangle.h" -#include "input.h" +#include "cata_imgui.h" +#include "input_context.h" +#include "imgui/imgui.h" +#include "output.h" class JsonArray; class JsonObject; @@ -24,22 +26,43 @@ class help public: static void load( const JsonObject &jo, const std::string &src ); static void reset(); - void display_help() const; + // TODO: Shouldn't be public + std::map>> help_texts; private: void load_object( const JsonObject &jo, const std::string &src ); void reset_instance(); - std::map> draw_menu( const catacurses::window &win, - int selected, std::map &hotkeys ) const; - static std::string get_note_colors(); - static std::string get_dir_grid(); // Modifier for each mods order int current_order_start = 0; std::string current_src; - std::map>> help_texts; }; +// Make pointer? help &get_help(); +class help_window : public cataimgui::window +{ + public: + explicit help_window(); + void show(); + protected: + void draw_controls() override; + cataimgui::bounds get_bounds() override; + private: + //void draw_tabless(); + //void draw_tabbed(); + //void draw_tab_contents( size_t tab ); + static std::string get_note_colors(); + static std::string get_dir_grid(); + input_context ctxt; + help &data = get_help(); + std::map hotkeys; + cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; + short mouse_selected_option; + short keyboard_selected_option; + short last_keyboard_selected_option; + void draw_category( translation &category_name, std::vector ¶graphs ); +}; + std::string get_hint(); #endif // CATA_SRC_HELP_H diff --git a/src/main_menu.cpp b/src/main_menu.cpp index 9a2ae6a275c5c..cfe97f6ed44bb 100644 --- a/src/main_menu.cpp +++ b/src/main_menu.cpp @@ -953,9 +953,11 @@ bool main_menu::opening_screen() } } else if( action == "CONFIRM" ) { switch( static_cast( sel1 ) ) { - case main_menu_opts::HELP: - get_help().display_help(); + case main_menu_opts::HELP: { + help_window hw; + hw.show(); break; + } case main_menu_opts::QUIT: return false; case main_menu_opts::TUTORIAL: From 7a37cdbc4d8cb1308ba6588a761939558129bee7 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:21:28 +0000 Subject: [PATCH 02/18] Simplify --- src/help.cpp | 57 +++++++++++++++++++++++++--------------------------- src/help.h | 13 ++++++------ 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 1d9791fd621d1..9134af9aa45e6 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -29,12 +29,14 @@ #include "translations.h" #include "ui_manager.h" -// Imgui planning +// Imgui migration planning //////////////////////////////////////////////////////////////////////// -// Tabular full screen menu -// 1 Tab per mod (overflow to an additional tab if more than 52 entries) -// General read/unread functionality -// Short desc for each category? +// Full screen category selection menu +// When you click a category/press a hotkey the categories paragraphs are presented with the categories name at the top, Esc to go back to selection +// Category paragraphs must word wrap and be scrollable +// If modded help is present, one tab per mod (overflow to an additional tab if more than 52 entries?), otherwise no tabs +// General read/unread functionality that changes the colour on the selection menu (no permanence for now) +// Split name into name and short desc for each category to make use of the extra space // Handling for tiny screens (mobile) class JsonObject; @@ -133,11 +135,8 @@ help_window::help_window() : cataimgui::window( "help", ImGuiWindowFlags_NoNavInputs ) { input_context ctxt( "DISPLAY_HELP", keyboard_mode::keychar ); - ctxt.register_cardinal(); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); - //ctxt.register_action( "NEXT_TAB" ); - //ctxt.register_action( "PREV_TAB" ); // Mouse selection ctxt.register_action( "SELECT" ); ctxt.register_action( "MOUSE_MOVE" ); @@ -153,11 +152,16 @@ help_window::help_window() : cataimgui::window( "help", void help_window::draw_controls() { - //if( ImGui::BeginTabBar( "idk" ) ) { - // ImGui::EndTabBar(); - //} + if( !selected_category ) { + draw_category_selection(); + } else { + draw_category( category.first, category.second ); + } +} + +void help_window::draw_category_selection() +{ mouse_selected_option = -1; - size_t ind = 0; for( const auto &text : data.help_texts ) { std::string cat_name; auto hotkey_it = hotkeys.find( text.first ); @@ -168,13 +172,8 @@ void help_window::draw_controls() cat_name += text.second.first.translated(); ImGui::Button( remove_color_tags( cat_name ).c_str() ); if( ImGui::IsItemHovered() ) { - mouse_selected_option = ind; + mouse_selected_option = hotkey_it->first; } - if( keyboard_selected_option != last_keyboard_selected_option && - keyboard_selected_option == short( ind ) && ImGui::IsWindowFocused() ) { - ImGui::SetKeyboardFocusHere( -1 ); - } - ind++; } } @@ -187,10 +186,12 @@ void help_window::draw_category( translation &category_name, std::vectorsecond.first, it->second.second ); + auto it = data.help_texts.find( selected ); + selected_category = it != data.help_texts.end(); + if( selected_category ) { + category = it->second; } } else if( action == "QUIT" ) { return; diff --git a/src/help.h b/src/help.h index d685b8905bef4..f95c8508e7bc4 100644 --- a/src/help.h +++ b/src/help.h @@ -36,7 +36,6 @@ class help std::string current_src; }; -// Make pointer? help &get_help(); class help_window : public cataimgui::window @@ -48,18 +47,18 @@ class help_window : public cataimgui::window void draw_controls() override; cataimgui::bounds get_bounds() override; private: - //void draw_tabless(); - //void draw_tabbed(); - //void draw_tab_contents( size_t tab ); static std::string get_note_colors(); static std::string get_dir_grid(); input_context ctxt; help &data = get_help(); std::map hotkeys; cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; - short mouse_selected_option; - short keyboard_selected_option; - short last_keyboard_selected_option; + int mouse_selected_option; + int keyboard_selected_option; + int last_keyboard_selected_option; + bool selected_category = false; + std::pair> &category = data.help_texts.begin()->second; + void draw_category_selection(); void draw_category( translation &category_name, std::vector ¶graphs ); }; From ec4f554ae746c2ed27b04860d87edf939ec82116 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:02:54 +0000 Subject: [PATCH 03/18] Basics down --- src/help.cpp | 110 ++++++++++++++++++++++++++++++++++++++------------- src/help.h | 8 +++- 2 files changed, 89 insertions(+), 29 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 9134af9aa45e6..b24a18ebbc444 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -131,10 +131,9 @@ std::string help_window::get_note_colors() } help_window::help_window() : cataimgui::window( "help", - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoNavInputs ) + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize ) { - input_context ctxt( "DISPLAY_HELP", keyboard_mode::keychar ); + ctxt = input_context( "DISPLAY_HELP", keyboard_mode::keychar ); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); // Mouse selection @@ -162,6 +161,7 @@ void help_window::draw_controls() void help_window::draw_category_selection() { mouse_selected_option = -1; + format_title( _( "Help" ) ); for( const auto &text : data.help_texts ) { std::string cat_name; auto hotkey_it = hotkeys.find( text.first ); @@ -172,29 +172,70 @@ void help_window::draw_category_selection() cat_name += text.second.first.translated(); ImGui::Button( remove_color_tags( cat_name ).c_str() ); if( ImGui::IsItemHovered() ) { - mouse_selected_option = hotkey_it->first; + mouse_selected_option = text.first; } } } +std::string help_window::seperator( int length, char c ) +{ + std::string ret = ""; + ret += std::string( length, c ); + ret += ""; + return ret; +} + +void help_window::format_title( const std::string translated_category_name ) +{ + std::string row3 = "║ "; + row3 += translated_category_name; + row3 += " ║"; + std::string div = seperator( remove_color_tags( row3 ).length() - 4, '=' ); + cataimgui::draw_colored_text( div ); + cataimgui::draw_colored_text( row3 ); + cataimgui::draw_colored_text( div ); + cataimgui::draw_colored_text( seperator( static_cast( wrap_width ), '_' ) ); + ImGui::NewLine(); +} + void help_window::draw_category( translation &category_name, std::vector ¶graphs ) { - cataimgui::draw_colored_text( category_name.translated() ); + format_title( category_name.translated() ); for( const translation ¶graph : paragraphs ) { + cataimgui::draw_colored_text( parse_tags_help_window( paragraph.translated() ), wrap_width ); ImGui::NewLine(); - ImGui::NewLine(); - cataimgui::draw_colored_text( paragraph.translated() ); } - mark_resized(); - ui_manager::redraw_invalidated(); - while( true ) { - ui_manager::redraw_invalidated(); - const std::string action = ctxt.handle_input( 50 ); - if( action == "CONFIRM" || action == "QUIT" ) { - selected_category = false; - return; + input_context cat_cxt( "DISPLAY_HELP_CATEGORY", keyboard_mode::keychar ); + cat_cxt.register_action( "QUIT" ); + cat_cxt.register_action( "CONFIRM" ); +} + +// Would ideally be merged with parse_tags() +std::string help_window::parse_tags_help_window( std::string translated_line ) +{ + if( translated_line == "" ) { + translated_line = get_note_colors(); + } else if( translated_line == "" ) { + translated_line = get_dir_grid(); + } + size_t pos = translated_line.find( "", pos, 1 ); + + std::string action = translated_line.substr( pos + 7, pos2 - pos - 7 ); + std::string replace = "" + + press_x( look_up_action( action ), "", "" ) + ""; + + if( replace.empty() ) { + debugmsg( "Help json: Unknown action: %s", action ); + } else { + translated_line = string_replace( + translated_line, "", replace ); } + + pos = translated_line.find( "second; + } else { + debugmsg( "Category not found" ); + } + } else if( action == "QUIT" ) { + return; + } } + while( selected_category ) { + ui_manager::redraw_invalidated(); + std::string action = ctxt.handle_input( 50 ); - if( action == "CONFIRM" ) { - auto it = data.help_texts.find( selected ); - selected_category = it != data.help_texts.end(); - if( selected_category ) { - category = it->second; + if( action == "CONFIRM" || action == "QUIT" ) { + selected_category = false; } - } else if( action == "QUIT" ) { - return; } } + } std::string get_hint() diff --git a/src/help.h b/src/help.h index f95c8508e7bc4..9e3bb7028593f 100644 --- a/src/help.h +++ b/src/help.h @@ -47,19 +47,25 @@ class help_window : public cataimgui::window void draw_controls() override; cataimgui::bounds get_bounds() override; private: + cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; + // TODO: Use padding values rather than arbitary reduction + float wrap_width = static_cast( str_width_to_pixels( TERMX ) ) * 0.95f; static std::string get_note_colors(); static std::string get_dir_grid(); + std::string seperator( int length, char c ); input_context ctxt; help &data = get_help(); std::map hotkeys; - cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; int mouse_selected_option; int keyboard_selected_option; int last_keyboard_selected_option; bool selected_category = false; + // TODO: Needs to be a pointer or iterator or something, currently assigning to it is overwriting the first help_text ;D std::pair> &category = data.help_texts.begin()->second; + std::string parse_tags_help_window( std::string translated_line ); void draw_category_selection(); void draw_category( translation &category_name, std::vector ¶graphs ); + void format_title( const std::string translated_category_name ); }; std::string get_hint(); From a5657e555c84d9037bd218454efb4e49ec9824c6 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:15:15 +0000 Subject: [PATCH 04/18] Trying and failing to get columns working --- src/help.cpp | 39 ++++++++++++++++++++++++++++----------- src/help.h | 7 +++++-- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index b24a18ebbc444..cf1f89e89017f 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -161,19 +161,36 @@ void help_window::draw_controls() void help_window::draw_category_selection() { mouse_selected_option = -1; + //~ Help menu header format_title( _( "Help" ) ); - for( const auto &text : data.help_texts ) { - std::string cat_name; - auto hotkey_it = hotkeys.find( text.first ); - if( hotkey_it != hotkeys.end() ) { - cat_name = hotkey_it->second.short_description(); - cat_name += ": "; - } - cat_name += text.second.first.translated(); - ImGui::Button( remove_color_tags( cat_name ).c_str() ); - if( ImGui::IsItemHovered() ) { - mouse_selected_option = text.first; + if( true /*&& ImGui::BeginTable( "abc", 3, ImGuiTableFlags_None, + ImVec2( window_width, window_height ) )*/ ) { + //ImGui::TableSetupColumn( "a", ImGuiTableColumnFlags_WidthStretch, + // static_cast( window_width / 2.0f ) ); + //ImGui::TableSetupColumn( "b", ImGuiTableColumnFlags_WidthStretch, + // static_cast( window_width / 2.0f ) ); + //ImGui::TableNextColumn(); + //size_t half_size = data.help_texts.size() / 2 + 1; + //size_t i = 0; + for( const auto &text : data.help_texts ) { + std::string cat_name; + auto hotkey_it = hotkeys.find( text.first ); + if( hotkey_it != hotkeys.end() ) { + cat_name = hotkey_it->second.short_description(); + cat_name += ": "; + } + cat_name += text.second.first.translated(); + ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); + if( ImGui::IsItemHovered() ) { + mouse_selected_option = text.first; + } + //i++; + //ImGui::TableNextRow(); + //if( i == half_size ) { + // ImGui::TableNextColumn(); + //} } + //ImGui::EndTable(); } } diff --git a/src/help.h b/src/help.h index 9e3bb7028593f..2c38c1c7670d8 100644 --- a/src/help.h +++ b/src/help.h @@ -48,8 +48,11 @@ class help_window : public cataimgui::window cataimgui::bounds get_bounds() override; private: cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; - // TODO: Use padding values rather than arbitary reduction - float wrap_width = static_cast( str_width_to_pixels( TERMX ) ) * 0.95f; + // 66 is optimal characters per line for reading? + float window_width = static_cast( str_width_to_pixels( TERMX ) ); + float window_height = static_cast( str_width_to_pixels( TERMY ) ); + float wrap_width = std::min( window_width * 0.95f, + static_cast( str_width_to_pixels( 66 ) ) ); static std::string get_note_colors(); static std::string get_dir_grid(); std::string seperator( int length, char c ); From d794190b2f18bb31ebf93fbb2cdb3d867a4ee89d Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:18:13 +0000 Subject: [PATCH 05/18] Working 2 column options :D --- src/help.cpp | 60 +++++++++++++++++++++++++++++----------------------- src/help.h | 6 ++++-- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index cf1f89e89017f..89a9b4e8c18ce 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -163,34 +163,42 @@ void help_window::draw_category_selection() mouse_selected_option = -1; //~ Help menu header format_title( _( "Help" ) ); - if( true /*&& ImGui::BeginTable( "abc", 3, ImGuiTableFlags_None, - ImVec2( window_width, window_height ) )*/ ) { - //ImGui::TableSetupColumn( "a", ImGuiTableColumnFlags_WidthStretch, - // static_cast( window_width / 2.0f ) ); - //ImGui::TableSetupColumn( "b", ImGuiTableColumnFlags_WidthStretch, - // static_cast( window_width / 2.0f ) ); - //ImGui::TableNextColumn(); - //size_t half_size = data.help_texts.size() / 2 + 1; - //size_t i = 0; - for( const auto &text : data.help_texts ) { - std::string cat_name; - auto hotkey_it = hotkeys.find( text.first ); - if( hotkey_it != hotkeys.end() ) { - cat_name = hotkey_it->second.short_description(); - cat_name += ": "; + if( ImGui::BeginTable( "Category Options", 3, ImGuiTableFlags_None ) ) { + ImGui::TableSetupColumn( "Left Column", ImGuiTableColumnFlags_WidthStretch, + static_cast( window_width / 2.0f ) ); + ImGui::TableSetupColumn( "Right Column", ImGuiTableColumnFlags_WidthStretch, + static_cast( window_width / 2.0f ) ); + int half_size = static_cast( data.help_texts.size() / 2.0f ) + 1; + auto half_it = data.help_texts.begin(); + std::advance( half_it, half_size ); + auto jt = data.help_texts.begin(); + std::advance( jt, half_size ); + for( auto it = data.help_texts.begin(); it != half_it; it++, jt++ ) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + display_category_option( *it ); + ImGui::TableNextColumn(); + if( jt != data.help_texts.end() ) { + display_category_option( *jt ); } - cat_name += text.second.first.translated(); - ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); - if( ImGui::IsItemHovered() ) { - mouse_selected_option = text.first; - } - //i++; - //ImGui::TableNextRow(); - //if( i == half_size ) { - // ImGui::TableNextColumn(); - //} } - //ImGui::EndTable(); + ImGui::EndTable(); + } +} + +void help_window::display_category_option( + const std::pair>> &help_text ) +{ + std::string cat_name; + auto hotkey_it = hotkeys.find( help_text.first ); + if( hotkey_it != hotkeys.end() ) { + cat_name = hotkey_it->second.short_description(); + cat_name += ": "; + } + cat_name += help_text.second.first.translated(); + ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); + if( ImGui::IsItemHovered() ) { + mouse_selected_option = help_text.first; } } diff --git a/src/help.h b/src/help.h index 2c38c1c7670d8..20cfd3de4aaec 100644 --- a/src/help.h +++ b/src/help.h @@ -27,7 +27,7 @@ class help static void load( const JsonObject &jo, const std::string &src ); static void reset(); // TODO: Shouldn't be public - std::map>> help_texts; + std::map>> help_texts; private: void load_object( const JsonObject &jo, const std::string &src ); void reset_instance(); @@ -50,7 +50,7 @@ class help_window : public cataimgui::window cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; // 66 is optimal characters per line for reading? float window_width = static_cast( str_width_to_pixels( TERMX ) ); - float window_height = static_cast( str_width_to_pixels( TERMY ) ); + //float window_height = static_cast( str_width_to_pixels( TERMY ) ); float wrap_width = std::min( window_width * 0.95f, static_cast( str_width_to_pixels( 66 ) ) ); static std::string get_note_colors(); @@ -68,6 +68,8 @@ class help_window : public cataimgui::window std::string parse_tags_help_window( std::string translated_line ); void draw_category_selection(); void draw_category( translation &category_name, std::vector ¶graphs ); + void display_category_option( const + std::pair>> &help_text ); void format_title( const std::string translated_category_name ); }; From 749a6c3befda9da9ce6238aaa3733e872977af1c Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 17:26:51 +0000 Subject: [PATCH 06/18] Tidy up/Consistent naming --- src/help.cpp | 76 ++++++++++++++++++++++++++-------------------------- src/help.h | 50 +++++++++++++++++++++------------- 2 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 89a9b4e8c18ce..40fbe49e2be7b 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -9,16 +9,11 @@ #include #include -#include "cata_imgui.h" -#include "input_context.h" -#include "imgui/imgui.h" -#include "output.h" - #include "action.h" -#include "catacharset.h" +#include "cata_imgui.h" #include "color.h" -#include "cursesdef.h" #include "debug.h" +#include "imgui/imgui.h" #include "input_context.h" #include "json_error.h" #include "output.h" @@ -31,7 +26,6 @@ // Imgui migration planning //////////////////////////////////////////////////////////////////////// -// Full screen category selection menu // When you click a category/press a hotkey the categories paragraphs are presented with the categories name at the top, Esc to go back to selection // Category paragraphs must word wrap and be scrollable // If modded help is present, one tab per mod (overflow to an additional tab if more than 52 entries?), otherwise no tabs @@ -61,7 +55,7 @@ void help::reset_instance() { current_order_start = 0; current_src = ""; - help_texts.clear(); + help_categories.clear(); } void help::load_object( const JsonObject &jo, const std::string &src ) @@ -71,16 +65,16 @@ void help::load_object( const JsonObject &jo, const std::string &src ) PATH_INFO::jsondir().generic_u8string() ) ); } if( src != current_src ) { - current_order_start = help_texts.empty() ? 0 : help_texts.crbegin()->first + 1; + current_order_start = help_categories.empty() ? 0 : help_categories.crbegin()->first + 1; current_src = src; } - std::vector messages; - jo.read( "messages", messages ); + help_category category; + jo.read( "messages", category.paragraphs ); translation name; - jo.read( "name", name ); + jo.read( "name", category.name ); const int modified_order = jo.get_int( "order" ) + current_order_start; - if( !help_texts.try_emplace( modified_order, std::make_pair( name, messages ) ).second ) { + if( !help_categories.try_emplace( modified_order, category ).second ) { jo.throw_error_at( "order", "\"order\" must be unique (per src)" ); } } @@ -143,7 +137,7 @@ help_window::help_window() : cataimgui::window( "help", ctxt.register_action( "ANY_INPUT" ); const hotkey_queue &hkq = hotkey_queue::alphabets(); input_event next_hotkey = ctxt.first_unassigned_hotkey( hkq ); - for( const auto &text : data.help_texts ) { + for( const auto &text : data.help_categories ) { hotkeys.emplace( text.first, next_hotkey ); next_hotkey = ctxt.next_unassigned_hotkey( hkq, next_hotkey ); } @@ -154,12 +148,13 @@ void help_window::draw_controls() if( !selected_category ) { draw_category_selection(); } else { - draw_category( category.first, category.second ); + draw_category(); } } void help_window::draw_category_selection() { + // Add one column display for tiny screens and screen reader users mouse_selected_option = -1; //~ Help menu header format_title( _( "Help" ) ); @@ -168,37 +163,36 @@ void help_window::draw_category_selection() static_cast( window_width / 2.0f ) ); ImGui::TableSetupColumn( "Right Column", ImGuiTableColumnFlags_WidthStretch, static_cast( window_width / 2.0f ) ); - int half_size = static_cast( data.help_texts.size() / 2.0f ) + 1; - auto half_it = data.help_texts.begin(); + int half_size = static_cast( data.help_categories.size() / 2.0f ) + 1; + auto half_it = data.help_categories.begin(); std::advance( half_it, half_size ); - auto jt = data.help_texts.begin(); + auto jt = data.help_categories.begin(); std::advance( jt, half_size ); - for( auto it = data.help_texts.begin(); it != half_it; it++, jt++ ) { + for( auto it = data.help_categories.begin(); it != half_it; it++, jt++ ) { ImGui::TableNextRow(); ImGui::TableNextColumn(); - display_category_option( *it ); + draw_category_option( it->first, it->second ); ImGui::TableNextColumn(); - if( jt != data.help_texts.end() ) { - display_category_option( *jt ); + if( jt != data.help_categories.end() ) { + draw_category_option( jt->first, jt->second ); } } ImGui::EndTable(); } } -void help_window::display_category_option( - const std::pair>> &help_text ) +void help_window::draw_category_option( const int &option, const help_category &category ) { std::string cat_name; - auto hotkey_it = hotkeys.find( help_text.first ); + auto hotkey_it = hotkeys.find( option ); if( hotkey_it != hotkeys.end() ) { cat_name = hotkey_it->second.short_description(); cat_name += ": "; } - cat_name += help_text.second.first.translated(); + cat_name += category.name.translated(); ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); if( ImGui::IsItemHovered() ) { - mouse_selected_option = help_text.first; + mouse_selected_option = option; } } @@ -212,6 +206,11 @@ std::string help_window::seperator( int length, char c ) void help_window::format_title( const std::string translated_category_name ) { + if( make_accessible ) { + cataimgui::draw_colored_text( translated_category_name ); + ImGui::NewLine(); + return; + } std::string row3 = "║ "; row3 += translated_category_name; row3 += " ║"; @@ -219,15 +218,17 @@ void help_window::format_title( const std::string translated_category_name ) cataimgui::draw_colored_text( div ); cataimgui::draw_colored_text( row3 ); cataimgui::draw_colored_text( div ); - cataimgui::draw_colored_text( seperator( static_cast( wrap_width ), '_' ) ); + cataimgui::draw_colored_text( seperator( TERMX, '_' ) ); ImGui::NewLine(); } -void help_window::draw_category( translation &category_name, std::vector ¶graphs ) +void help_window::draw_category() { - format_title( category_name.translated() ); - for( const translation ¶graph : paragraphs ) { - cataimgui::draw_colored_text( parse_tags_help_window( paragraph.translated() ), wrap_width ); + format_title( category.name.translated() ); + for( const translation ¶graph : category.paragraphs ) { + std::string translated_paragraph = paragraph.translated(); + parse_tags_help_window( translated_paragraph ); + cataimgui::draw_colored_text( translated_paragraph, wrap_width ); ImGui::NewLine(); } input_context cat_cxt( "DISPLAY_HELP_CATEGORY", keyboard_mode::keychar ); @@ -235,8 +236,8 @@ void help_window::draw_category( translation &category_name, std::vector" ) { translated_line = get_note_colors(); @@ -260,7 +261,6 @@ std::string help_window::parse_tags_help_window( std::string translated_line ) pos = translated_line.find( "second; } else { diff --git a/src/help.h b/src/help.h index 20cfd3de4aaec..4b0f78e16e203 100644 --- a/src/help.h +++ b/src/help.h @@ -11,6 +11,7 @@ #include "cata_imgui.h" #include "input_context.h" #include "imgui/imgui.h" +#include "options.h" #include "output.h" class JsonArray; @@ -21,13 +22,18 @@ namespace catacurses class window; } // namespace catacurses +struct help_category { + translation name; + std::vector paragraphs; +}; + class help { public: static void load( const JsonObject &jo, const std::string &src ); static void reset(); // TODO: Shouldn't be public - std::map>> help_texts; + std::map help_categories; private: void load_object( const JsonObject &jo, const std::string &src ); void reset_instance(); @@ -47,30 +53,38 @@ class help_window : public cataimgui::window void draw_controls() override; cataimgui::bounds get_bounds() override; private: - cataimgui::bounds bounds{ 0.0f, 0.0f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; - // 66 is optimal characters per line for reading? + // Fullscreen float window_width = static_cast( str_width_to_pixels( TERMX ) ); - //float window_height = static_cast( str_width_to_pixels( TERMY ) ); - float wrap_width = std::min( window_width * 0.95f, - static_cast( str_width_to_pixels( 66 ) ) ); - static std::string get_note_colors(); - static std::string get_dir_grid(); - std::string seperator( int length, char c ); - input_context ctxt; + float window_height = static_cast( str_width_to_pixels( TERMY ) ); + float wrap_width = window_width * 0.95f; + cataimgui::bounds bounds{ 0.f, 0.f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; + + // 66 is optimal characters per line for reading? + //float window_width = static_cast( wrap_width ) * 2.025f; + //float window_height = static_cast( str_width_to_pixels( TERMY ) ) * 0.8f; + //float wrap_width = std::min( window_width * 0.95f, static_cast( str_width_to_pixels( 66 ) ) ); + //cataimgui::bounds bounds{ 0.f, 0.f, window_width, window_height }; + help &data = get_help(); + bool make_accessible = get_option( "SCREEN_READER_MODE" ); + input_context ctxt; std::map hotkeys; + + void draw_category_selection(); + void format_title( const std::string translated_category_name ); + std::string seperator( int length, char c ); + + void draw_category_option( const int &option, const help_category &category ); int mouse_selected_option; int keyboard_selected_option; int last_keyboard_selected_option; bool selected_category = false; - // TODO: Needs to be a pointer or iterator or something, currently assigning to it is overwriting the first help_text ;D - std::pair> &category = data.help_texts.begin()->second; - std::string parse_tags_help_window( std::string translated_line ); - void draw_category_selection(); - void draw_category( translation &category_name, std::vector ¶graphs ); - void display_category_option( const - std::pair>> &help_text ); - void format_title( const std::string translated_category_name ); + help_category category; + + void draw_category(); + void parse_tags_help_window( std::string &translated_line ); + static std::string get_note_colors(); + static std::string get_dir_grid(); }; std::string get_hint(); From 0865e06d6f26311e76d1330967823e1c98120791 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:03:56 +0000 Subject: [PATCH 07/18] Add hotkey and arrow key + enter support --- src/help.cpp | 18 ++++++++++++++++-- src/help.h | 1 - 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 40fbe49e2be7b..7a88a2dbdb54b 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -194,6 +194,9 @@ void help_window::draw_category_option( const int &option, const help_category & if( ImGui::IsItemHovered() ) { mouse_selected_option = option; } + if( ImGui::IsItemActive() ) { + keyboard_selected_option = option; + } } std::string help_window::seperator( int length, char c ) @@ -270,18 +273,29 @@ cataimgui::bounds help_window::get_bounds() void help_window::show() { - int selected = -1; while( true ) { + int selected = -1; while( !selected_category ) { ui_manager::redraw_invalidated(); std::string action = ctxt.handle_input( 50 ); + input_event input = ctxt.get_raw_input(); if( action == "SELECT" && mouse_selected_option != -1 ) { action = "CONFIRM"; selected = mouse_selected_option; } + for( const auto &hotkey_entry : hotkeys ) { + if( input == hotkey_entry.second ) { + action = "CONFIRM"; + selected = hotkey_entry.first; + break; + } + } - if( action == "CONFIRM" && selected != -1 ) { + if( action == "CONFIRM" ) { + if( selected == -1 ) { + selected = keyboard_selected_option; + } auto it = data.help_categories.find( selected ); selected_category = it != data.help_categories.end(); if( selected_category ) { diff --git a/src/help.h b/src/help.h index 4b0f78e16e203..5674fbc960d4f 100644 --- a/src/help.h +++ b/src/help.h @@ -77,7 +77,6 @@ class help_window : public cataimgui::window void draw_category_option( const int &option, const help_category &category ); int mouse_selected_option; int keyboard_selected_option; - int last_keyboard_selected_option; bool selected_category = false; help_category category; From 0b4a5e69f11241957de1db1344858b6a7f45ae6f Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:46:49 +0000 Subject: [PATCH 08/18] Unread/read highlighting that persists per session --- src/help.cpp | 15 ++++++++++----- src/help.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 7a88a2dbdb54b..2e10cd2665f7e 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -26,11 +26,7 @@ // Imgui migration planning //////////////////////////////////////////////////////////////////////// -// When you click a category/press a hotkey the categories paragraphs are presented with the categories name at the top, Esc to go back to selection -// Category paragraphs must word wrap and be scrollable // If modded help is present, one tab per mod (overflow to an additional tab if more than 52 entries?), otherwise no tabs -// General read/unread functionality that changes the colour on the selection menu (no permanence for now) -// Split name into name and short desc for each category to make use of the extra space // Handling for tiny screens (mobile) class JsonObject; @@ -56,6 +52,7 @@ void help::reset_instance() current_order_start = 0; current_src = ""; help_categories.clear(); + read_categories.clear(); } void help::load_object( const JsonObject &jo, const std::string &src ) @@ -158,6 +155,7 @@ void help_window::draw_category_selection() mouse_selected_option = -1; //~ Help menu header format_title( _( "Help" ) ); + // Split the categories in half if( ImGui::BeginTable( "Category Options", 3, ImGuiTableFlags_None ) ) { ImGui::TableSetupColumn( "Left Column", ImGuiTableColumnFlags_WidthStretch, static_cast( window_width / 2.0f ) ); @@ -190,7 +188,13 @@ void help_window::draw_category_option( const int &option, const help_category & cat_name += ": "; } cat_name += category.name.translated(); - ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); + if( data.read_categories.find( option ) != data.read_categories.end() ) { + ImGui::PushStyleColor( ImGuiCol_Text, c_light_gray ); + ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); + ImGui::PopStyleColor(); + } else { + ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); + } if( ImGui::IsItemHovered() ) { mouse_selected_option = option; } @@ -296,6 +300,7 @@ void help_window::show() if( selected == -1 ) { selected = keyboard_selected_option; } + data.read_categories.insert( selected ); auto it = data.help_categories.find( selected ); selected_category = it != data.help_categories.end(); if( selected_category ) { diff --git a/src/help.h b/src/help.h index 5674fbc960d4f..5e49d5fcfbfb4 100644 --- a/src/help.h +++ b/src/help.h @@ -34,6 +34,8 @@ class help static void reset(); // TODO: Shouldn't be public std::map help_categories; + // Only persists per session + std::unordered_set read_categories; private: void load_object( const JsonObject &jo, const std::string &src ); void reset_instance(); From 4ffc96e09abe00c84c1a53a8a7e7773dc5c59084 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:06:03 +0000 Subject: [PATCH 09/18] Maintain title position --- src/help.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 2e10cd2665f7e..e96ed527cb56f 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -24,11 +24,6 @@ #include "translations.h" #include "ui_manager.h" -// Imgui migration planning -//////////////////////////////////////////////////////////////////////// -// If modded help is present, one tab per mod (overflow to an additional tab if more than 52 entries?), otherwise no tabs -// Handling for tiny screens (mobile) - class JsonObject; help &get_help() @@ -122,7 +117,8 @@ std::string help_window::get_note_colors() } help_window::help_window() : cataimgui::window( "help", - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize ) + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse ) { ctxt = input_context( "DISPLAY_HELP", keyboard_mode::keychar ); ctxt.register_action( "QUIT" ); @@ -232,15 +228,18 @@ void help_window::format_title( const std::string translated_category_name ) void help_window::draw_category() { format_title( category.name.translated() ); - for( const translation ¶graph : category.paragraphs ) { - std::string translated_paragraph = paragraph.translated(); - parse_tags_help_window( translated_paragraph ); - cataimgui::draw_colored_text( translated_paragraph, wrap_width ); - ImGui::NewLine(); + if( ImGui::BeginTable( "HELP_PARAGRAPHS", 1, + ImGuiTableFlags_ScrollY ) ) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + for( const translation ¶graph : category.paragraphs ) { + std::string translated_paragraph = paragraph.translated(); + parse_tags_help_window( translated_paragraph ); + cataimgui::draw_colored_text( translated_paragraph, wrap_width ); + ImGui::NewLine(); + } + ImGui::EndTable(); } - input_context cat_cxt( "DISPLAY_HELP_CATEGORY", keyboard_mode::keychar ); - cat_cxt.register_action( "QUIT" ); - cat_cxt.register_action( "CONFIRM" ); } // Would ideally be merged with parse_tags()? From 20914810859ca61ceed5321d717f76d8283cf9ca Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:29:12 +0000 Subject: [PATCH 10/18] Allow moving between categories --- src/help.cpp | 41 +++++++++++++++++++++++++++++++---------- src/help.h | 2 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index e96ed527cb56f..747963371fc74 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -128,6 +128,10 @@ help_window::help_window() : cataimgui::window( "help", ctxt.register_action( "MOUSE_MOVE" ); // Generated shortcuts ctxt.register_action( "ANY_INPUT" ); + // Switching between categories while open + ctxt.register_leftright(); + ctxt.register_action( "PREV_TAB" ); + ctxt.register_action( "NEXT_TAB" ); const hotkey_queue &hkq = hotkey_queue::alphabets(); input_event next_hotkey = ctxt.first_unassigned_hotkey( hkq ); for( const auto &text : data.help_categories ) { @@ -191,10 +195,8 @@ void help_window::draw_category_option( const int &option, const help_category & } else { ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); } - if( ImGui::IsItemHovered() ) { + if( ImGui::IsItemHovered() || ImGui::IsItemActive() ) { mouse_selected_option = option; - } - if( ImGui::IsItemActive() ) { keyboard_selected_option = option; } } @@ -227,12 +229,13 @@ void help_window::format_title( const std::string translated_category_name ) void help_window::draw_category() { - format_title( category.name.translated() ); + const help_category &cat = data.help_categories[cid]; + format_title( cat.name.translated() ); if( ImGui::BeginTable( "HELP_PARAGRAPHS", 1, ImGuiTableFlags_ScrollY ) ) { ImGui::TableNextRow(); ImGui::TableNextColumn(); - for( const translation ¶graph : category.paragraphs ) { + for( const translation ¶graph : cat.paragraphs ) { std::string translated_paragraph = paragraph.translated(); parse_tags_help_window( translated_paragraph ); cataimgui::draw_colored_text( translated_paragraph, wrap_width ); @@ -299,13 +302,12 @@ void help_window::show() if( selected == -1 ) { selected = keyboard_selected_option; } - data.read_categories.insert( selected ); - auto it = data.help_categories.find( selected ); - selected_category = it != data.help_categories.end(); + selected_category = data.help_categories.find( selected ) != data.help_categories.end(); if( selected_category ) { - category = it->second; + cid = selected; + data.read_categories.insert( cid ); } else { - debugmsg( "Category not found" ); + debugmsg( "Category not found: option %s", selected ); } } else if( action == "QUIT" ) { return; @@ -318,6 +320,25 @@ void help_window::show() if( action == "CONFIRM" || action == "QUIT" ) { selected_category = false; } + if( action == "LEFT" || action == "PREV_TAB" ) { + auto it = data.help_categories.find( cid ); + if( it != data.help_categories.begin() ) { + cid = ( --it )->first; + } else { + cid = data.help_categories.rbegin()->first; + } + data.read_categories.insert( cid ); + } + if( action == "RIGHT" || action == "NEXT_TAB" ) { + auto it = data.help_categories.find( cid ); + it++; + if( it != data.help_categories.end() ) { + cid = it->first; + } else { + cid = data.help_categories.begin()->first; + } + data.read_categories.insert( cid ); + } } } diff --git a/src/help.h b/src/help.h index 5e49d5fcfbfb4..cdb1b319b46c9 100644 --- a/src/help.h +++ b/src/help.h @@ -80,7 +80,7 @@ class help_window : public cataimgui::window int mouse_selected_option; int keyboard_selected_option; bool selected_category = false; - help_category category; + int cid; void draw_category(); void parse_tags_help_window( std::string &translated_line ); From b66983cc62fb4703b1dce3fdde8d6019f2003cc0 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:42:20 +0000 Subject: [PATCH 11/18] Refactor option selection --- src/help.cpp | 73 ++++++++++++++++++++-------------------------------- src/help.h | 10 +++---- 2 files changed, 32 insertions(+), 51 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 747963371fc74..6cb8325206ce8 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -142,7 +141,7 @@ help_window::help_window() : cataimgui::window( "help", void help_window::draw_controls() { - if( !selected_category ) { + if( !has_selected_category ) { draw_category_selection(); } else { draw_category(); @@ -151,8 +150,8 @@ void help_window::draw_controls() void help_window::draw_category_selection() { - // Add one column display for tiny screens and screen reader users - mouse_selected_option = -1; + // TODO: Add one column display for tiny screens and screen reader users + selected_option = -1; //~ Help menu header format_title( _( "Help" ) ); // Split the categories in half @@ -195,9 +194,8 @@ void help_window::draw_category_option( const int &option, const help_category & } else { ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); } - if( ImGui::IsItemHovered() || ImGui::IsItemActive() ) { - mouse_selected_option = option; - keyboard_selected_option = option; + if( ImGui::IsItemHovered() ) { + selected_option = option; } } @@ -211,7 +209,8 @@ std::string help_window::seperator( int length, char c ) void help_window::format_title( const std::string translated_category_name ) { - if( make_accessible ) { + cataimgui::PushMonoFont(); + if( get_option( "SCREEN_READER_MODE" ) ) { cataimgui::draw_colored_text( translated_category_name ); ImGui::NewLine(); return; @@ -225,11 +224,12 @@ void help_window::format_title( const std::string translated_category_name ) cataimgui::draw_colored_text( div ); cataimgui::draw_colored_text( seperator( TERMX, '_' ) ); ImGui::NewLine(); + ImGui::PopFont(); } void help_window::draw_category() { - const help_category &cat = data.help_categories[cid]; + const help_category &cat = data.help_categories[loaded_option]; format_title( cat.name.translated() ); if( ImGui::BeginTable( "HELP_PARAGRAPHS", 1, ImGuiTableFlags_ScrollY ) ) { @@ -280,64 +280,47 @@ cataimgui::bounds help_window::get_bounds() void help_window::show() { while( true ) { - int selected = -1; - while( !selected_category ) { + while( !has_selected_category ) { ui_manager::redraw_invalidated(); std::string action = ctxt.handle_input( 50 ); input_event input = ctxt.get_raw_input(); - if( action == "SELECT" && mouse_selected_option != -1 ) { - action = "CONFIRM"; - selected = mouse_selected_option; - } for( const auto &hotkey_entry : hotkeys ) { if( input == hotkey_entry.second ) { action = "CONFIRM"; - selected = hotkey_entry.first; + selected_option = hotkey_entry.first; break; } } - if( action == "CONFIRM" ) { - if( selected == -1 ) { - selected = keyboard_selected_option; - } - selected_category = data.help_categories.find( selected ) != data.help_categories.end(); - if( selected_category ) { - cid = selected; - data.read_categories.insert( cid ); + if( selected_option != -1 && ( action == "SELECT" || action == "CONFIRM" ) ) { + has_selected_category = data.help_categories.find( selected_option ) != data.help_categories.end(); + if( has_selected_category ) { + loaded_option = selected_option; + data.read_categories.insert( loaded_option ); } else { - debugmsg( "Category not found: option %s", selected ); + debugmsg( "Category not found: option %s", selected_option ); } } else if( action == "QUIT" ) { return; } } - while( selected_category ) { + while( has_selected_category ) { ui_manager::redraw_invalidated(); std::string action = ctxt.handle_input( 50 ); if( action == "CONFIRM" || action == "QUIT" ) { - selected_category = false; - } - if( action == "LEFT" || action == "PREV_TAB" ) { - auto it = data.help_categories.find( cid ); - if( it != data.help_categories.begin() ) { - cid = ( --it )->first; - } else { - cid = data.help_categories.rbegin()->first; - } - data.read_categories.insert( cid ); - } - if( action == "RIGHT" || action == "NEXT_TAB" ) { - auto it = data.help_categories.find( cid ); + has_selected_category = false; + } else if( action == "LEFT" || action == "PREV_TAB" ) { + auto it = data.help_categories.find( loaded_option ); + loaded_option = it != data.help_categories.begin() ? ( --it )->first : + data.help_categories.rbegin()->first; + data.read_categories.insert( loaded_option ); + } else if( action == "RIGHT" || action == "NEXT_TAB" ) { + auto it = data.help_categories.find( loaded_option ); it++; - if( it != data.help_categories.end() ) { - cid = it->first; - } else { - cid = data.help_categories.begin()->first; - } - data.read_categories.insert( cid ); + loaded_option = it != data.help_categories.end() ? it->first : data.help_categories.begin()->first; + data.read_categories.insert( loaded_option ); } } } diff --git a/src/help.h b/src/help.h index cdb1b319b46c9..5e4e998c5d90c 100644 --- a/src/help.h +++ b/src/help.h @@ -34,7 +34,7 @@ class help static void reset(); // TODO: Shouldn't be public std::map help_categories; - // Only persists per session + // Only persists per load (eg resets on menu -> game, game -> menu) std::unordered_set read_categories; private: void load_object( const JsonObject &jo, const std::string &src ); @@ -68,7 +68,6 @@ class help_window : public cataimgui::window //cataimgui::bounds bounds{ 0.f, 0.f, window_width, window_height }; help &data = get_help(); - bool make_accessible = get_option( "SCREEN_READER_MODE" ); input_context ctxt; std::map hotkeys; @@ -77,10 +76,9 @@ class help_window : public cataimgui::window std::string seperator( int length, char c ); void draw_category_option( const int &option, const help_category &category ); - int mouse_selected_option; - int keyboard_selected_option; - bool selected_category = false; - int cid; + int selected_option; + bool has_selected_category = false; + int loaded_option; void draw_category(); void parse_tags_help_window( std::string &translated_line ); From e89090a282c1ac494f38363528032a4a05ca4ce5 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sat, 14 Dec 2024 00:56:47 +0000 Subject: [PATCH 12/18] Make suggested changes --- src/help.cpp | 178 ++++++++++++++++++++++++++++++++++++--------------- src/help.h | 8 +-- 2 files changed, 130 insertions(+), 56 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 6cb8325206ce8..78f4a2b458127 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -101,24 +101,26 @@ std::string help_window::get_dir_grid() return movement; } -std::string help_window::get_note_colors() +void help_window::note_colors() { - std::string text = _( "Note colors: " ); + ImGui::Text( _( "Note colors: " ) ); + ImGui::SameLine( 0.f, 0.f ); for( const auto &color_pair : get_note_color_names() ) { // The color index is not translatable, but the name is. //~ %1$s: note color abbreviation, %2$s: note color name - text += string_format( pgettext( "note color", "%1$s:%2$s, " ), - colorize( color_pair.first, color_pair.second.color ), - color_pair.second.name ); + cataimgui::TextColoredParagraph( c_white, string_format( pgettext( "note color", "%1$s:%2$s, " ), + colorize( color_pair.first, color_pair.second.color ), + color_pair.second.name ) ); + // TODO: Has a stray comma at the end + ImGui::SameLine( 0.f, 0.f ); } - - return text; } help_window::help_window() : cataimgui::window( "help", ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse ) { + // TODO: ImGui auto arrow key handling doesn't work with ImTui ctxt = input_context( "DISPLAY_HELP", keyboard_mode::keychar ); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); @@ -155,7 +157,7 @@ void help_window::draw_category_selection() //~ Help menu header format_title( _( "Help" ) ); // Split the categories in half - if( ImGui::BeginTable( "Category Options", 3, ImGuiTableFlags_None ) ) { + if( ImGui::BeginTable( "Category Options", 2, ImGuiTableFlags_None ) ) { ImGui::TableSetupColumn( "Left Column", ImGuiTableColumnFlags_WidthStretch, static_cast( window_width / 2.0f ) ); ImGui::TableSetupColumn( "Right Column", ImGuiTableColumnFlags_WidthStretch, @@ -166,7 +168,6 @@ void help_window::draw_category_selection() auto jt = data.help_categories.begin(); std::advance( jt, half_size ); for( auto it = data.help_categories.begin(); it != half_it; it++, jt++ ) { - ImGui::TableNextRow(); ImGui::TableNextColumn(); draw_category_option( it->first, it->second ); ImGui::TableNextColumn(); @@ -199,46 +200,111 @@ void help_window::draw_category_option( const int &option, const help_category & } } -std::string help_window::seperator( int length, char c ) -{ - std::string ret = ""; - ret += std::string( length, c ); - ret += ""; - return ret; -} - void help_window::format_title( const std::string translated_category_name ) { - cataimgui::PushMonoFont(); if( get_option( "SCREEN_READER_MODE" ) ) { - cataimgui::draw_colored_text( translated_category_name ); + cataimgui::TextColoredParagraph( c_white, translated_category_name ); ImGui::NewLine(); return; } - std::string row3 = "║ "; - row3 += translated_category_name; - row3 += " ║"; - std::string div = seperator( remove_color_tags( row3 ).length() - 4, '=' ); - cataimgui::draw_colored_text( div ); - cataimgui::draw_colored_text( row3 ); - cataimgui::draw_colored_text( div ); - cataimgui::draw_colored_text( seperator( TERMX, '_' ) ); - ImGui::NewLine(); + const float title_length = ImGui::CalcTextSize( remove_color_tags( + translated_category_name ).c_str() ).x; + cataimgui::PushMonoFont(); + const int sep_len = std::ceil( ( title_length / ImGui::CalcTextSize( "═" ).x ) + 2 ); + ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); + + ImGui::Text( "╔" ); + ImGui::SameLine( 0.f, 0.f ); + for( int i = sep_len; i > 0; i-- ) { + ImGui::Text( "═" ); + ImGui::SameLine( 0.f, 0.f ); + } + ImGui::Text( "╗" ); + // Using the matching box character doesn't look good bc there's forced(?) y spacing on NewLine + ImGui::Text( "┇ " ); + ImGui::SameLine( 0.f, 0.f ); + ImGui::PopStyleColor(); ImGui::PopFont(); + cataimgui::TextColoredParagraph( c_white, translated_category_name ); + cataimgui::PushMonoFont(); + ImGui::SameLine( 0.f, 0.f ); + ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); + ImGui::Text( " ┇" ); + ImGui::Text( "╚" ); + ImGui::SameLine( 0.f, 0.f ); + for( int i = sep_len; i > 0; i-- ) { + ImGui::Text( "═" ); + ImGui::SameLine( 0.f, 0.f ); + } + ImGui::Text( "╝" ); + ImGui::PopStyleColor(); + ImGui::PopFont(); + ImGui::NewLine(); + ImGui::PushStyleColor( ImGuiCol_Separator, c_light_blue ); + ImGui::Separator(); + ImGui::PopStyleColor(); + ImGui::NewLine(); } +//void help_window::format_subtitle( const std::string translated_category_name ) +//{ +// if( get_option( "SCREEN_READER_MODE" ) ) { +// cataimgui::TextColoredParagraph( c_white, translated_category_name ); +// ImGui::NewLine(); +// return; +// } +// const float title_length = ImGui::CalcTextSize( remove_color_tags( +// translated_category_name ).c_str() ).x; +// cataimgui::PushMonoFont(); +// const int sep_len = std::ceil( ( title_length / ImGui::CalcTextSize( "═" ).x ) + 4 ); +// ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); +// for( int i = sep_len; i > 0; i-- ) { +// ImGui::Text( "▁" ); +// ImGui::SameLine( 0.f, 0.f ); +// } +// ImGui::NewLine(); +// // Using the matching box character doesn't look good bc there's forced(?) y spacing on NewLine +// ImGui::Text( "▏ " ); +// ImGui::SameLine( 0.f, 0.f ); +// ImGui::PopStyleColor(); +// ImGui::PopFont(); +// cataimgui::TextColoredParagraph( c_white, translated_category_name ); +// cataimgui::PushMonoFont(); +// ImGui::SameLine( 0.f, 0.f ); +// ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); +// ImGui::Text( " ▕" ); +// for( int i = sep_len; i > 0; i-- ) { +// ImGui::Text( "▔" ); +// ImGui::SameLine( 0.f, 0.f ); +// } +// ImGui::PopStyleColor(); +// ImGui::PopFont(); +// ImGui::NewLine(); +// ImGui::PushStyleColor( ImGuiCol_Separator, c_light_blue ); +// ImGui::Separator(); +// ImGui::PopStyleColor(); +//} + void help_window::draw_category() { const help_category &cat = data.help_categories[loaded_option]; format_title( cat.name.translated() ); + // Use a table so we can scroll the category paragraphs without the title if( ImGui::BeginTable( "HELP_PARAGRAPHS", 1, ImGuiTableFlags_ScrollY ) ) { ImGui::TableNextRow(); ImGui::TableNextColumn(); - for( const translation ¶graph : cat.paragraphs ) { - std::string translated_paragraph = paragraph.translated(); - parse_tags_help_window( translated_paragraph ); - cataimgui::draw_colored_text( translated_paragraph, wrap_width ); + for( const std::string &translated_paragraph : translated_paragraphs ) { + if( translated_paragraph == "" ) { + note_colors(); + continue; + } else if( translated_paragraph == "" ) { + static const std::string dir_grid = get_dir_grid(); + cataimgui::draw_colored_text( dir_grid, wrap_width ); + continue; + } + cataimgui::TextColoredParagraph( c_white, translated_paragraph ); + ImGui::NewLine(); ImGui::NewLine(); } ImGui::EndTable(); @@ -246,29 +312,31 @@ void help_window::draw_category() } // Would ideally be merged with parse_tags()? -void help_window::parse_tags_help_window( std::string &translated_line ) +void help_window::parse_tags_help_window() { - if( translated_line == "" ) { - translated_line = get_note_colors(); - } else if( translated_line == "" ) { - translated_line = get_dir_grid(); - } - size_t pos = translated_line.find( "", pos, 1 ); - - std::string action = translated_line.substr( pos + 7, pos2 - pos - 7 ); - std::string replace = "" + - press_x( look_up_action( action ), "", "" ) + ""; - - if( replace.empty() ) { - debugmsg( "Help json: Unknown action: %s", action ); - } else { - translated_line = string_replace( - translated_line, "", replace ); + for( std::string &translated_paragraph : translated_paragraphs ) { + if( translated_paragraph == "" ) { + continue; + } else if( translated_paragraph == "" ) { + continue; } + size_t pos = translated_paragraph.find( "", pos, 1 ); + + std::string action = translated_paragraph.substr( pos + 7, pos2 - pos - 7 ); + std::string replace = "" + + press_x( look_up_action( action ), "", "" ) + ""; + + if( replace.empty() ) { + debugmsg( "Help json: Unknown action: %s", action ); + } else { + translated_paragraph = string_replace( translated_paragraph, "", + replace ); + } - pos = translated_line.find( " translated_paragraphs; + void parse_tags_help_window(); void draw_category(); - void parse_tags_help_window( std::string &translated_line ); - static std::string get_note_colors(); - static std::string get_dir_grid(); + void note_colors(); + std::string get_dir_grid(); }; std::string get_hint(); From d04e24bb89a93cb2c4ce4d59fd44c5115f3eab57 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Sun, 15 Dec 2024 02:11:40 -0800 Subject: [PATCH 13/18] remove the item spacing in category titles so the ascii art looks right --- src/help.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 78f4a2b458127..de487270384ee 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -103,7 +103,7 @@ std::string help_window::get_dir_grid() void help_window::note_colors() { - ImGui::Text( _( "Note colors: " ) ); + ImGui::TextUnformatted( _( "Note colors: " ) ); ImGui::SameLine( 0.f, 0.f ); for( const auto &color_pair : get_note_color_names() ) { // The color index is not translatable, but the name is. @@ -209,19 +209,19 @@ void help_window::format_title( const std::string translated_category_name ) } const float title_length = ImGui::CalcTextSize( remove_color_tags( translated_category_name ).c_str() ).x; + ImGui::PushStyleVarY( ImGuiStyleVar_ItemSpacing, 0 ); cataimgui::PushMonoFont(); const int sep_len = std::ceil( ( title_length / ImGui::CalcTextSize( "═" ).x ) + 2 ); ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); - ImGui::Text( "╔" ); ImGui::SameLine( 0.f, 0.f ); for( int i = sep_len; i > 0; i-- ) { ImGui::Text( "═" ); ImGui::SameLine( 0.f, 0.f ); } + int x = ImGui::GetCursorPosX(); ImGui::Text( "╗" ); - // Using the matching box character doesn't look good bc there's forced(?) y spacing on NewLine - ImGui::Text( "┇ " ); + ImGui::Text( "║ " ); ImGui::SameLine( 0.f, 0.f ); ImGui::PopStyleColor(); ImGui::PopFont(); @@ -229,7 +229,8 @@ void help_window::format_title( const std::string translated_category_name ) cataimgui::PushMonoFont(); ImGui::SameLine( 0.f, 0.f ); ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); - ImGui::Text( " ┇" ); + ImGui::SetCursorPosX( x ); + ImGui::Text( "║" ); ImGui::Text( "╚" ); ImGui::SameLine( 0.f, 0.f ); for( int i = sep_len; i > 0; i-- ) { @@ -239,6 +240,8 @@ void help_window::format_title( const std::string translated_category_name ) ImGui::Text( "╝" ); ImGui::PopStyleColor(); ImGui::PopFont(); + ImGui::PopStyleVar(); + ImGui::NewLine(); ImGui::PushStyleColor( ImGuiCol_Separator, c_light_blue ); ImGui::Separator(); From e72374cc9afb8c61c574725a5ba23dcc9d726d11 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sun, 15 Dec 2024 13:48:14 +0000 Subject: [PATCH 14/18] Fix ImTui scrolling and fix paragraphs not changing on switching tab --- src/help.cpp | 30 +++++++++++++++++++++++++++--- src/help.h | 1 + 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index de487270384ee..80cef8f75da6a 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -66,7 +66,7 @@ void help::load_object( const JsonObject &jo, const std::string &src ) jo.read( "name", category.name ); const int modified_order = jo.get_int( "order" ) + current_order_start; if( !help_categories.try_emplace( modified_order, category ).second ) { - jo.throw_error_at( "order", "\"order\" must be unique (per src)" ); + jo.throw_error_at( "order", "\"order\" must be unique per source" ); } } @@ -120,7 +120,7 @@ help_window::help_window() : cataimgui::window( "help", ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse ) { - // TODO: ImGui auto arrow key handling doesn't work with ImTui + ctxt = input_context( "DISPLAY_HELP", keyboard_mode::keychar ); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); @@ -129,6 +129,10 @@ help_window::help_window() : cataimgui::window( "help", ctxt.register_action( "MOUSE_MOVE" ); // Generated shortcuts ctxt.register_action( "ANY_INPUT" ); + // Scrolling open category + ctxt.register_action( "PAGE_UP" ); + ctxt.register_action( "PAGE_DOWN" ); + ctxt.register_updown(); // Switching between categories while open ctxt.register_leftright(); ctxt.register_action( "PREV_TAB" ); @@ -295,6 +299,7 @@ void help_window::draw_category() // Use a table so we can scroll the category paragraphs without the title if( ImGui::BeginTable( "HELP_PARAGRAPHS", 1, ImGuiTableFlags_ScrollY ) ) { + cataimgui::set_scroll( s ); ImGui::TableNextRow(); ImGui::TableNextColumn(); for( const std::string &translated_paragraph : translated_paragraphs ) { @@ -386,17 +391,36 @@ void help_window::show() ui_manager::redraw_invalidated(); std::string action = ctxt.handle_input( 50 ); - if( action == "CONFIRM" || action == "QUIT" ) { + if( action == "UP" ) { + s = cataimgui::scroll::line_up; + } else if( action == "DOWN" ) { + s = cataimgui::scroll::line_down; + } else if( action == "PAGE_UP" ) { + s = cataimgui::scroll::page_up; + } else if( action == "PAGE_DOWN" ) { + s = cataimgui::scroll::page_down; + } else if( action == "CONFIRM" || action == "QUIT" ) { has_selected_category = false; } else if( action == "LEFT" || action == "PREV_TAB" ) { auto it = data.help_categories.find( loaded_option ); loaded_option = it != data.help_categories.begin() ? ( --it )->first : data.help_categories.rbegin()->first; + translated_paragraphs.clear(); + const help_category &cat = data.help_categories[loaded_option]; + for( const translation ¶graph : cat.paragraphs ) { + translated_paragraphs.emplace_back( paragraph.translated() ); + } + parse_tags_help_window(); data.read_categories.insert( loaded_option ); } else if( action == "RIGHT" || action == "NEXT_TAB" ) { auto it = data.help_categories.find( loaded_option ); it++; loaded_option = it != data.help_categories.end() ? it->first : data.help_categories.begin()->first; + translated_paragraphs.clear(); + const help_category &cat = data.help_categories[loaded_option]; + for( const translation ¶graph : cat.paragraphs ) { + translated_paragraphs.emplace_back( paragraph.translated() ); + } data.read_categories.insert( loaded_option ); } } diff --git a/src/help.h b/src/help.h index 99db1ac020dc3..4be05e373d0f1 100644 --- a/src/help.h +++ b/src/help.h @@ -84,6 +84,7 @@ class help_window : public cataimgui::window void draw_category(); void note_colors(); std::string get_dir_grid(); + cataimgui::scroll s; }; std::string get_hint(); From 47f98df320a3d5585bb155fe8ddd6b906000c4e6 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:17:53 +0000 Subject: [PATCH 15/18] Minor refactor --- src/help.cpp | 65 +++++++++++++++++++++++----------------------------- src/help.h | 2 ++ 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 80cef8f75da6a..26db2b27fa626 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -213,44 +213,42 @@ void help_window::format_title( const std::string translated_category_name ) } const float title_length = ImGui::CalcTextSize( remove_color_tags( translated_category_name ).c_str() ).x; + ImGui::PushStyleVarX( ImGuiStyleVar_ItemSpacing, 0 ); ImGui::PushStyleVarY( ImGuiStyleVar_ItemSpacing, 0 ); + ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); + ImGui::PushStyleColor( ImGuiCol_Separator, c_light_blue ); cataimgui::PushMonoFont(); const int sep_len = std::ceil( ( title_length / ImGui::CalcTextSize( "═" ).x ) + 2 ); - ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); ImGui::Text( "╔" ); - ImGui::SameLine( 0.f, 0.f ); + ImGui::SameLine(); for( int i = sep_len; i > 0; i-- ) { ImGui::Text( "═" ); - ImGui::SameLine( 0.f, 0.f ); + ImGui::SameLine(); } - int x = ImGui::GetCursorPosX(); + const int x = ImGui::GetCursorPosX(); ImGui::Text( "╗" ); ImGui::Text( "║ " ); - ImGui::SameLine( 0.f, 0.f ); - ImGui::PopStyleColor(); - ImGui::PopFont(); - cataimgui::TextColoredParagraph( c_white, translated_category_name ); - cataimgui::PushMonoFont(); - ImGui::SameLine( 0.f, 0.f ); - ImGui::PushStyleColor( ImGuiCol_Text, c_light_blue ); + ImGui::SameLine(); + const ImVec2 text_pos = ImGui::GetCursorPos(); ImGui::SetCursorPosX( x ); ImGui::Text( "║" ); ImGui::Text( "╚" ); - ImGui::SameLine( 0.f, 0.f ); + ImGui::SameLine(); for( int i = sep_len; i > 0; i-- ) { ImGui::Text( "═" ); - ImGui::SameLine( 0.f, 0.f ); + ImGui::SameLine(); } ImGui::Text( "╝" ); - ImGui::PopStyleColor(); - ImGui::PopFont(); - ImGui::PopStyleVar(); - ImGui::NewLine(); - ImGui::PushStyleColor( ImGuiCol_Separator, c_light_blue ); ImGui::Separator(); - ImGui::PopStyleColor(); ImGui::NewLine(); + const ImVec2 end_pos = ImGui::GetCursorPos(); + ImGui::PopFont(); + ImGui::PopStyleColor( 2 ); + ImGui::PopStyleVar( 2 ); + ImGui::SetCursorPos( text_pos ); + cataimgui::TextColoredParagraph( c_white, translated_category_name ); + ImGui::SetCursorPos( end_pos ); } //void help_window::format_subtitle( const std::string translated_category_name ) @@ -373,12 +371,7 @@ void help_window::show() has_selected_category = data.help_categories.find( selected_option ) != data.help_categories.end(); if( has_selected_category ) { loaded_option = selected_option; - translated_paragraphs.clear(); - const help_category &cat = data.help_categories[loaded_option]; - for( const translation ¶graph : cat.paragraphs ) { - translated_paragraphs.emplace_back( paragraph.translated() ); - } - parse_tags_help_window(); + swap_translated_paragraphs(); data.read_categories.insert( loaded_option ); } else { debugmsg( "Category not found: option %s", selected_option ); @@ -405,27 +398,27 @@ void help_window::show() auto it = data.help_categories.find( loaded_option ); loaded_option = it != data.help_categories.begin() ? ( --it )->first : data.help_categories.rbegin()->first; - translated_paragraphs.clear(); - const help_category &cat = data.help_categories[loaded_option]; - for( const translation ¶graph : cat.paragraphs ) { - translated_paragraphs.emplace_back( paragraph.translated() ); - } - parse_tags_help_window(); + swap_translated_paragraphs(); data.read_categories.insert( loaded_option ); } else if( action == "RIGHT" || action == "NEXT_TAB" ) { auto it = data.help_categories.find( loaded_option ); it++; loaded_option = it != data.help_categories.end() ? it->first : data.help_categories.begin()->first; - translated_paragraphs.clear(); - const help_category &cat = data.help_categories[loaded_option]; - for( const translation ¶graph : cat.paragraphs ) { - translated_paragraphs.emplace_back( paragraph.translated() ); - } + swap_translated_paragraphs(); data.read_categories.insert( loaded_option ); } } } +} +void help_window::swap_translated_paragraphs() +{ + translated_paragraphs.clear(); + const help_category &cat = data.help_categories[loaded_option]; + for( const translation ¶graph : cat.paragraphs ) { + translated_paragraphs.emplace_back( paragraph.translated() ); + } + parse_tags_help_window(); } std::string get_hint() diff --git a/src/help.h b/src/help.h index 4be05e373d0f1..b1563914d9588 100644 --- a/src/help.h +++ b/src/help.h @@ -78,6 +78,8 @@ class help_window : public cataimgui::window int selected_option; bool has_selected_category = false; int loaded_option; + + void swap_translated_paragraphs(); std::vector translated_paragraphs; void parse_tags_help_window(); From e720f0d0259d3379c54df463fe630886d25b53f1 Mon Sep 17 00:00:00 2001 From: Daniel Brooks Date: Sun, 15 Dec 2024 10:55:35 -0800 Subject: [PATCH 16/18] make the help window full screen and resize it when the game resizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do this by not specifying the size in pixels but in percent. We want the window to be 100%, or 1.0×, the size of the game window. --- src/help.cpp | 10 ++++------ src/help.h | 12 ------------ 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/help.cpp b/src/help.cpp index 26db2b27fa626..28acc9cfa7c18 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -162,10 +162,8 @@ void help_window::draw_category_selection() format_title( _( "Help" ) ); // Split the categories in half if( ImGui::BeginTable( "Category Options", 2, ImGuiTableFlags_None ) ) { - ImGui::TableSetupColumn( "Left Column", ImGuiTableColumnFlags_WidthStretch, - static_cast( window_width / 2.0f ) ); - ImGui::TableSetupColumn( "Right Column", ImGuiTableColumnFlags_WidthStretch, - static_cast( window_width / 2.0f ) ); + ImGui::TableSetupColumn( "Left Column", ImGuiTableColumnFlags_WidthStretch, 1.0f ); + ImGui::TableSetupColumn( "Right Column", ImGuiTableColumnFlags_WidthStretch, 1.0f ); int half_size = static_cast( data.help_categories.size() / 2.0f ) + 1; auto half_it = data.help_categories.begin(); std::advance( half_it, half_size ); @@ -306,7 +304,7 @@ void help_window::draw_category() continue; } else if( translated_paragraph == "" ) { static const std::string dir_grid = get_dir_grid(); - cataimgui::draw_colored_text( dir_grid, wrap_width ); + cataimgui::draw_colored_text( dir_grid ); continue; } cataimgui::TextColoredParagraph( c_white, translated_paragraph ); @@ -348,7 +346,7 @@ void help_window::parse_tags_help_window() cataimgui::bounds help_window::get_bounds() { - return bounds; + return {0, 0, 1.0, 1.0}; } void help_window::show() diff --git a/src/help.h b/src/help.h index b1563914d9588..d0c849796b95e 100644 --- a/src/help.h +++ b/src/help.h @@ -55,18 +55,6 @@ class help_window : public cataimgui::window void draw_controls() override; cataimgui::bounds get_bounds() override; private: - // Fullscreen - float window_width = static_cast( str_width_to_pixels( TERMX ) ); - float window_height = static_cast( str_width_to_pixels( TERMY ) ); - float wrap_width = window_width * 0.95f; - cataimgui::bounds bounds{ 0.f, 0.f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; - - // 66 is optimal characters per line for reading? - //float window_width = static_cast( wrap_width ) * 2.025f; - //float window_height = static_cast( str_width_to_pixels( TERMY ) ) * 0.8f; - //float wrap_width = std::min( window_width * 0.95f, static_cast( str_width_to_pixels( 66 ) ) ); - //cataimgui::bounds bounds{ 0.f, 0.f, window_width, window_height }; - help &data = get_help(); input_context ctxt; std::map hotkeys; From 5eec26059dd2f85b8099ee8c5498593a72421385 Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:54:34 +0000 Subject: [PATCH 17/18] Add more functionality to the json messages, remove hardcoded special tags DRAW_NOTE_COLORS is redundant, it already shows when adding a map note HELP_DRAW_DIRECTIONS can be done in json instead now --- data/core/help.json | 48 ++++++++++----- doc/HELP_MENU.md | 1 + src/help.cpp | 143 ++++++++++++++++++++++---------------------- src/help.h | 9 ++- src/options.cpp | 4 +- 5 files changed, 113 insertions(+), 92 deletions(-) diff --git a/data/core/help.json b/data/core/help.json index 10af37f5ceacf..6c18863717742 100644 --- a/data/core/help.json +++ b/data/core/help.json @@ -15,8 +15,25 @@ "order": 1, "name": "Movement", "messages": [ - "Movement is performed using the numpad, the arrow keys, or vikeys.", - "", + "Movement is typically performed using the numpad, vikeys, the mouse or arrow keys. Here are the layouts for numpad and vikeys, where the central bind is to wait in place:", + { + "force_monospaced": "7 8 9 y k u\n \\|/ \\|/ \n4-5-6 h-.-l\n /|\\ /|\\ \n1 2 3 b j n\n" + }, + "Movement is also possible using the arrow keys by first enabling the \"Diagonal movement with cursor keys and modifiers\" setting in the Interface tab to one of these four modes:", + "- Numpad Emulation: In this mode you hold Ctrl throughout, first pressing a direction which will then modify further key presses to be in altered by that direction, for example if you first press Up, then further Left, Up, Right and Down presses will become NW, N, NE, and wait respectively.", + { + "force_monospaced": " After Up After Right\n N NE\n NW O NE O SE E\n" + }, + "- CW/CCW: In this mode holding Shift modifies each key 45 degrees clockwise while holding Ctrl modifies each key 45 degrees counter-clockwise.", + { + "force_monospaced": " With Shift With Ctrl\n NE NW\n NW SW SE SW SE NE\n" + }, + "- L/R Tilt: In this mode holding Shift/Ctrl makes Left and Right behave as NW/SW and NE/SE respectively. Up and Down behave normally regardless of modifiers.", + { + "force_monospaced": " With Shift With Ctrl\n N NW\n NW S NE SW S SE\n" + }, + "- Diagonal Lock: In this mode holding Shift or Ctrl results in only diagonal combinations of two directions being accepted for example Ctrl + Up + Right becomes NE.", + { "seperator": "color_green" }, "Each step will take 100 movement points (or more, depending on the terrain); you will then replenish a variable amount of movement points, depending on many factors (press to see the exact amount).", "To attempt to hit a monster with your weapon, simply move into it.", "You may find doors, ('+'); these may be opened with or closed with . Some doors are locked. Locked doors, windows, and some other obstacles can be destroyed by smashing them (, then choose a direction). Smashing down obstacles is much easier with a good weapon or a strong character.", @@ -276,18 +293,23 @@ { "type": "help", "order": 19, - "name": "Description of map symbols", + "name": "Overmap key", "messages": [ - "MAP SYMBOLS:", + "OVERMAP SYMBOLS:", ". Field - Empty grassland with occasional wild fruit.", + ", Meadow - .", "F Forest - May be dense or sparse. Movement will be slowed. You might be able to forage for food here.", - "│─└┌┐┘├┴┤┬┼ Road - Safe from burrowing animals.", - "H= Highway - Like roads, but lined with guard rails.", - "|- Bridge - Helps you cross rivers.", - "R River - Most creatures cannot swim across them, but you can.", - "O Parking lot - Empty lot, few items. Mostly useless.", - "^>v< House - Filled with a variety of items. Good place to sleep.", - "^>v< Gas station - A good place to collect gasoline. Risk of explosion.", + "│─└┌┐┘├┴┤┬┼ Forest Trail - A path through the forest. Faster and more open than walking through the forest proper. Consider breaking line of sight through the forest if anything does catch up with you.", + "T Trailhead - The start of a trail. If you're lucky you'll find a map and maybe even a working vehicle here.", + "F Freshwater Swamp - .", + "│─└┌┐┘├┴┤┬┼ Road - Safe from burrowing animals.", + ">-< Roadbridge - Helps you cross rivers.", + ". Stream - A small body of water that you can drive over.", + "RR River - Most creatures cannot swim across them, but you can.", + "## Lake/Ocean - .", + "X Radio Tower - A tall tower useful for getting a good view of the surrounding area. Beware any fauna that may have made its home here.", + "^>v< House - Come in many forms. Good place to find basic supplies and everyday tools.", + "^>v< Gas station - A good place to collect gasoline.", "^>v< Pharmacy - The best source for vital medications.", "^>v< Grocery store - A good source of canned food and other supplies.", "^>v< Hardware store - Home to tools, melee weapons and crafting goods.", @@ -296,9 +318,7 @@ "^>v< Gun store - Firearms and ammunition are very valuable.", "^>v< Clothing store - High-capacity clothing, some light armor.", "^>v< Library - Home to books, both entertaining and informative.", - "^>v< Man-made buildings - The pointed side indicates the front door.", - " There are many others out there… search for them!", - "" + "^>v< Man-made buildings - The pointed side indicates the front door." ] }, { diff --git a/doc/HELP_MENU.md b/doc/HELP_MENU.md index bcc4a51d09dcf..89cb4e4c73b4d 100644 --- a/doc/HELP_MENU.md +++ b/doc/HELP_MENU.md @@ -1,3 +1,4 @@ +BEFOREMERGE Update # Help Menu The help menu consists of scrollable categorised help pages that would ideally explain everything a new survivor needs to know, as well as any information the game can't convey clearly in an immersive way. diff --git a/src/help.cpp b/src/help.cpp index 26db2b27fa626..901e5173d6223 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -49,6 +49,13 @@ void help::reset_instance() read_categories.clear(); } +enum message_modifier { + MM_NORMAL = 0, // Normal message + MM_SUBTITLE, // Formatted subtitle + MM_MONOFONT, // Forced monofont for fixed space diagrams + MM_SEPERATOR // ImGui seperator, value is the color to use +}; + void help::load_object( const JsonObject &jo, const std::string &src ) { if( src == "dda" ) { @@ -59,60 +66,32 @@ void help::load_object( const JsonObject &jo, const std::string &src ) current_order_start = help_categories.empty() ? 0 : help_categories.crbegin()->first + 1; current_src = src; } + help_category category; - jo.read( "messages", category.paragraphs ); translation name; jo.read( "name", category.name ); - const int modified_order = jo.get_int( "order" ) + current_order_start; - if( !help_categories.try_emplace( modified_order, category ).second ) { - jo.throw_error_at( "order", "\"order\" must be unique per source" ); - } -} -std::string help_window::get_dir_grid() -{ - static const std::array movearray = {{ - ACTION_MOVE_FORTH_LEFT, ACTION_MOVE_FORTH, ACTION_MOVE_FORTH_RIGHT, - ACTION_MOVE_LEFT, ACTION_PAUSE, ACTION_MOVE_RIGHT, - ACTION_MOVE_BACK_LEFT, ACTION_MOVE_BACK, ACTION_MOVE_BACK_RIGHT - } - }; - - std::string movement = " \n" - " \\ | / \\ | /\n" - " \\|/ \\|/\n" - "---- ----\n" - " /|\\ /|\\\n" - " / | \\ / | \\\n" - " "; - - for( action_id dir : movearray ) { - std::vector keys = keys_bound_to( dir, /*maximum_modifier_count=*/0 ); - for( size_t i = 0; i < 2; i++ ) { - movement = string_replace( movement, "<" + action_ident( dir ) + string_format( "_%d>", i ), - i < keys.size() - ? string_format( "%s", - keys[i].short_description() ) - : "?" ); + for( JsonValue jv : jo.get_array( "messages" ) ) { + if( jv.test_string() ) { + category.paragraphs.emplace_back( to_translation( jv.get_string() ), MM_NORMAL ); + } else { + JsonObject jobj = jv.get_object(); + if( jobj.has_string( "subtitle" ) ) { + category.paragraphs.emplace_back( to_translation( jobj.get_string( "subtitle" ) ), MM_SUBTITLE ); + } else if( jobj.has_string( "force_monospaced" ) ) { + category.paragraphs.emplace_back( to_translation( jobj.get_string( "force_monospaced" ) ), + MM_MONOFONT ); + } else if( jobj.has_string( "seperator" ) ) { + category.paragraphs.emplace_back( no_translation( jobj.get_string( "seperator" ) ), MM_SEPERATOR ); + } } } - return movement; -} -void help_window::note_colors() -{ - ImGui::TextUnformatted( _( "Note colors: " ) ); - ImGui::SameLine( 0.f, 0.f ); - for( const auto &color_pair : get_note_color_names() ) { - // The color index is not translatable, but the name is. - //~ %1$s: note color abbreviation, %2$s: note color name - cataimgui::TextColoredParagraph( c_white, string_format( pgettext( "note color", "%1$s:%2$s, " ), - colorize( color_pair.first, color_pair.second.color ), - color_pair.second.name ) ); - // TODO: Has a stray comma at the end - ImGui::SameLine( 0.f, 0.f ); + const int modified_order = jo.get_int( "order" ) + current_order_start; + if( !help_categories.try_emplace( modified_order, category ).second ) { + jo.throw_error_at( "order", "\"order\" must be unique per source" ); } } @@ -193,6 +172,10 @@ void help_window::draw_category_option( const int &option, const help_category & } cat_name += category.name.translated(); if( data.read_categories.find( option ) != data.read_categories.end() ) { + if( screen_reader ) { + //~ Prefix for options that has already been viewed when using a screen reader + cat_name = _( "(read) " ) + cat_name; + } ImGui::PushStyleColor( ImGuiCol_Text, c_light_gray ); ImGui::Selectable( remove_color_tags( cat_name ).c_str() ); ImGui::PopStyleColor(); @@ -206,7 +189,7 @@ void help_window::draw_category_option( const int &option, const help_category & void help_window::format_title( const std::string translated_category_name ) { - if( get_option( "SCREEN_READER_MODE" ) ) { + if( screen_reader ) { cataimgui::TextColoredParagraph( c_white, translated_category_name ); ImGui::NewLine(); return; @@ -300,16 +283,37 @@ void help_window::draw_category() cataimgui::set_scroll( s ); ImGui::TableNextRow(); ImGui::TableNextColumn(); - for( const std::string &translated_paragraph : translated_paragraphs ) { - if( translated_paragraph == "" ) { - note_colors(); - continue; - } else if( translated_paragraph == "" ) { - static const std::string dir_grid = get_dir_grid(); - cataimgui::draw_colored_text( dir_grid, wrap_width ); - continue; + for( const std::pair &translated_paragraph : + translated_paragraphs ) { + switch( translated_paragraph.second ) { + case MM_NORMAL: + cataimgui::TextColoredParagraph( c_white, translated_paragraph.first ); + break; + case MM_SUBTITLE: + // BEFOREMERGE: Do something different + cataimgui::TextColoredParagraph( c_white, translated_paragraph.first ); + break; + case MM_MONOFONT: + cataimgui::PushMonoFont(); + cataimgui::TextColoredParagraph( c_white, translated_paragraph.first ); + ImGui::PopFont(); + break; + // Causing a missing EndChild() ImGui crash? + //case MM_SEPERATOR: { + // nc_color col = get_all_colors().name_to_color( translated_paragraph.first ); + // ImGui::PushStyleColor( ImGuiCol_Separator, cataimgui::imvec4_from_color( col ) ); + // ImGui::Separator(); + // ImGui::PopStyleColor(); + // break; + //} + // Temporary until crash is worked out + case MM_SEPERATOR: + ImGui::Separator(); + break; + default: + debugmsg( "Unexpected help message modifier" ); + continue; } - cataimgui::TextColoredParagraph( c_white, translated_paragraph ); ImGui::NewLine(); ImGui::NewLine(); } @@ -317,31 +321,26 @@ void help_window::draw_category() } } -// Would ideally be merged with parse_tags()? -void help_window::parse_tags_help_window() +// Would ideally share parse_tags() code for keybinds +void help_window::parse_keybind_tags() { - for( std::string &translated_paragraph : translated_paragraphs ) { - if( translated_paragraph == "" ) { - continue; - } else if( translated_paragraph == "" ) { - continue; - } - size_t pos = translated_paragraph.find( " &translated_paragraph : translated_paragraphs ) { + std::string &text = translated_paragraph.first; + size_t pos = text.find( "", pos, 1 ); + size_t pos2 = text.find( ">", pos, 1 ); - std::string action = translated_paragraph.substr( pos + 7, pos2 - pos - 7 ); + std::string action = text.substr( pos + 7, pos2 - pos - 7 ); std::string replace = "" + press_x( look_up_action( action ), "", "" ) + ""; if( replace.empty() ) { debugmsg( "Help json: Unknown action: %s", action ); } else { - translated_paragraph = string_replace( translated_paragraph, "", - replace ); + text = string_replace( text, "", replace ); } - pos = translated_paragraph.find( " ¶graph : cat.paragraphs ) { + translated_paragraphs.emplace_back( paragraph.first.translated(), paragraph.second ); } - parse_tags_help_window(); + parse_keybind_tags(); } std::string get_hint() diff --git a/src/help.h b/src/help.h index b1563914d9588..bf5a5de260e41 100644 --- a/src/help.h +++ b/src/help.h @@ -24,7 +24,7 @@ class window; struct help_category { translation name; - std::vector paragraphs; + std::vector> paragraphs; }; class help @@ -60,6 +60,7 @@ class help_window : public cataimgui::window float window_height = static_cast( str_width_to_pixels( TERMY ) ); float wrap_width = window_width * 0.95f; cataimgui::bounds bounds{ 0.f, 0.f, static_cast( str_width_to_pixels( TERMX ) ), static_cast( str_height_to_pixels( TERMY ) ) }; + const bool screen_reader = get_option( "SCREEN_READER_MODE" ); // 66 is optimal characters per line for reading? //float window_width = static_cast( wrap_width ) * 2.025f; @@ -80,12 +81,10 @@ class help_window : public cataimgui::window int loaded_option; void swap_translated_paragraphs(); - std::vector translated_paragraphs; - void parse_tags_help_window(); + std::vector> translated_paragraphs; + void parse_keybind_tags(); void draw_category(); - void note_colors(); - std::string get_dir_grid(); cataimgui::scroll s; }; diff --git a/src/options.cpp b/src/options.cpp index 012932f23050b..39c9580f71f34 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -2029,7 +2029,9 @@ void options_manager::add_options_interface() * Example 3: Press → while holding Shift and ← results in input rejection */ - to_translation( "Allows diagonal movement with cursor keys using CTRL and SHIFT modifiers. Diagonal movement action keys are taken from keybindings, so you need these to be configured." ), { { "none", to_translation( "None" ) }, { "mode1", to_translation( "Mode 1: Numpad Emulation" ) }, { "mode2", to_translation( "Mode 2: CW/CCW" ) }, { "mode3", to_translation( "Mode 3: L/R Tilt" ) }, { "mode4", to_translation( "Mode 4: Diagonal Lock" ) } }, + // BEFOREMERGE: Check if this works with curses + to_translation( "Allows diagonal movement with cursor keys using CTRL and SHIFT modifiers. Diagonal movement action keys are taken from keybindings, so you need these to be configured. See the movement category in the help menu for full descriptions of the options." ), + { { "none", to_translation( "None" ) }, { "mode1", to_translation( "Mode 1: Numpad Emulation" ) }, { "mode2", to_translation( "Mode 2: CW/CCW" ) }, { "mode3", to_translation( "Mode 3: L/R Tilt" ) }, { "mode4", to_translation( "Mode 4: Diagonal Lock" ) } }, "none", COPT_CURSES_HIDE ); add_empty_line(); From c9cf0fa331df26d0145839aa1bb3e6b70e4a87da Mon Sep 17 00:00:00 2001 From: Procyonae <45432782+Procyonae@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:15:26 +0000 Subject: [PATCH 18/18] Fix rebase --- src/help.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/help.h b/src/help.h index 56f7932183122..7c8382e4e8c2c 100644 --- a/src/help.h +++ b/src/help.h @@ -55,6 +55,7 @@ class help_window : public cataimgui::window void draw_controls() override; cataimgui::bounds get_bounds() override; private: + const bool screen_reader = get_option( "SCREEN_READER_MODE" ); help &data = get_help(); input_context ctxt; std::map hotkeys;