1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
#include "help.h"
#include <algorithm>
#include <vector>
#include "action.h"
#include "catacharset.h"
#include "cursesdef.h"
#include "input.h"
#include "json.h"
#include "output.h"
#include "path_info.h"
#include "text_snippets.h"
#include "translations.h"
help &get_help()
{
static help single_instance;
return single_instance;
}
void help::load()
{
read_from_file_optional_json( FILENAMES["help"], [&]( JsonIn & jsin ) {
deserialize( jsin );
} );
}
void help::deserialize( JsonIn &jsin )
{
hotkeys.clear();
std::string note_colors = get_note_colors();
std::string dir_grid = get_dir_grid();
jsin.start_array();
while( !jsin.end_array() ) {
JsonObject jo = jsin.get_object();
std::vector<std::string> messages;
jo.read( "messages", messages );
for( auto &line : messages ) {
if( line == "<DRAW_NOTE_COLORS>" ) {
line = string_replace( line, "<DRAW_NOTE_COLORS>", note_colors );
continue;
} else if( line == "<HELP_DRAW_DIRECTIONS>" ) {
line = string_replace( line, "<HELP_DRAW_DIRECTIONS>", dir_grid );
continue;
}
}
std::string name = jo.get_string( "name" );
help_texts[jo.get_int( "order" )] = std::make_pair( name, messages );
hotkeys.push_back( get_hotkeys( name ) );
}
}
std::string help::get_dir_grid()
{
static const std::array<action_id, 9> movearray = {{
ACTION_MOVE_NW, ACTION_MOVE_N, ACTION_MOVE_NE,
ACTION_MOVE_W, ACTION_PAUSE, ACTION_MOVE_E,
ACTION_MOVE_SW, ACTION_MOVE_S, ACTION_MOVE_SE
}
};
std::string movement = "<LEFTUP_0> <UP_0> <RIGHTUP_0> <LEFTUP_1> <UP_1> <RIGHTUP_1>\n"\
" \\ | / \\ | /\n"\
" \\|/ \\|/\n"\
"<LEFT_0>--<pause_0>--<RIGHT_0> <LEFT_1>--<pause_1>--<RIGHT_1>\n"\
" /|\\ /|\\\n"\
" / | \\ / | \\\n"\
"<LEFTDOWN_0> <DOWN_0> <RIGHTDOWN_0> <LEFTDOWN_1> <DOWN_1> <RIGHTDOWN_1>";
for( auto dir : movearray ) {
std::vector<char> keys = keys_bound_to( dir );
for( size_t i = 0; i < keys.size(); i++ ) {
movement = string_replace( movement, "<" + action_ident( dir ) + string_format( "_%d>", i ),
string_format( "<color_light_blue>%s</color>", keys[i] ) );
}
}
return movement;
}
void help::draw_menu( const catacurses::window &win )
{
werase( win );
int y = fold_and_print( win, 0, 1, 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;
int second_column = getmaxx( win ) / 2;
for( size_t i = 0; i < help_texts.size(); i++ ) {
std::string cat_name = _( help_texts[i].first.c_str() );
if( i < half_size ) {
second_column = std::max( second_column, utf8_width( cat_name ) + 4 );
}
shortcut_print( win, y + i % half_size, ( i < half_size ? 1 : second_column ),
c_white, c_light_blue, cat_name );
}
wrefresh( win );
}
std::string help::get_note_colors()
{
std::string text = _( "Note colors: " );
for( auto color_pair : get_note_color_names() ) {
// The color index is not translatable, but the name is.
text += string_format( "<color_%s>%s:%s</color>, ",
string_from_color( get_note_color( color_pair.first ) ),
color_pair.first.c_str(), _( color_pair.second.c_str() ) );
}
return text;
}
void help::display_help()
{
catacurses::window w_help_border = catacurses::newwin( FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH,
( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0,
( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 );
catacurses::window w_help = catacurses::newwin( FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 2,
1 + static_cast<int>( ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ),
1 + static_cast<int>( ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 ) );
bool needs_refresh = true;
ctxt.register_cardinal();
ctxt.register_action( "QUIT" );
ctxt.register_action( "CONFIRM" );
// for the menu shortcuts
ctxt.register_action( "ANY_INPUT" );
std::string action;
do {
if( needs_refresh ) {
draw_border( w_help_border, BORDER_COLOR, _( " HELP " ) );
wrefresh( w_help_border );
draw_menu( w_help );
catacurses::refresh();
needs_refresh = false;
}
action = ctxt.handle_input();
std::string sInput = ctxt.get_raw_input().text;
for( size_t i = 0; i < hotkeys.size(); ++i ) {
for( const std::string &hotkey : hotkeys[i] ) {
if( sInput == hotkey ) {
std::vector<std::string> i18n_help_texts;
i18n_help_texts.reserve( help_texts[i].second.size() );
std::transform( help_texts[i].second.begin(), help_texts[i].second.end(),
std::back_inserter( i18n_help_texts ), [&]( std::string & line ) {
std::string line_proc = _( line.c_str() );
size_t pos = line_proc.find( "<press_", 0, 7 );
while( pos != std::string::npos ) {
size_t pos2 = line_proc.find( ">", pos, 1 );
std::string action = line_proc.substr( pos + 7, pos2 - pos - 7 );
auto replace = "<color_light_blue>" + press_x( look_up_action( action ), "", "" ) + "</color>";
if( replace.empty() ) {
debugmsg( "Help json: Unknown action: %s", action );
} else {
line_proc = string_replace( line_proc, "<press_" + action + ">", replace );
}
pos = line_proc.find( "<press_", pos2, 7 );
}
return line_proc;
} );
multipage( w_help, i18n_help_texts );
action = "CONFIRM";
break;
}
}
}
needs_refresh = true;
} while( action != "QUIT" );
}
std::string get_hint()
{
return SNIPPET.get( SNIPPET.assign( "hint" ) );
}
|