diff --git a/src/catacurse.h b/src/catacurse.h index b376843715197..b3423d07a52f9 100644 --- a/src/catacurse.h +++ b/src/catacurse.h @@ -130,6 +130,7 @@ int mvwhline(WINDOW *win, int y, int x, chtype ch, int n); int mvwvline(WINDOW *win, int y, int x, chtype ch, int n); int wrefresh(WINDOW *win); +int redrawwin(WINDOW *win); int refresh(void); int getch(void); int wgetch(WINDOW *win); diff --git a/src/construction.cpp b/src/construction.cpp index 06285fd1795dd..d5a91c3577e9a 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -198,7 +198,7 @@ void construction_menu() ctxt.register_action("QUIT"); ctxt.register_action("ANY_INPUT"); ctxt.register_action("HELP_KEYBINDINGS"); - + ctxt.assign_windows({(&w_con)}); std::string hotkeys = ctxt.get_available_single_char_hotkeys(); do { diff --git a/src/crafting.cpp b/src/crafting.cpp index 2d9ad7376476e..561670f3b2f55 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -1200,9 +1200,6 @@ int recipe::print_time(WINDOW *w, int ypos, int xpos, int width, return fold_and_print( w, ypos, xpos, width, col, text ); } -// ui.cpp -extern bool lcmatch(const std::string &str, const std::string &findstr); - template bool lcmatch_any(const std::vector< std::vector > &list_of_list, const std::string &filter) { diff --git a/src/cursesport.cpp b/src/cursesport.cpp index ba1b62b36bdb6..6a3ac2b07d4c8 100644 --- a/src/cursesport.cpp +++ b/src/cursesport.cpp @@ -265,6 +265,13 @@ int wrefresh(WINDOW *win) if( win != nullptr && win->draw ) { curses_drawwindow(win); } + +#ifdef TILES + void try_update(); + if (win == mainwin) { + try_update(); + } +#endif return 1; } @@ -617,6 +624,19 @@ int clearok(WINDOW *win) return 1; } +int redrawwin(WINDOW* win) +{ + if (! win) { + return 0; + } + win->draw = true; + for (int i = 0; i < win->height; i++) { + win->line[i].touched = true; + } + return 1; +} + + //gets the max x of a window (the width) int getmaxx(WINDOW *win) { diff --git a/src/game.cpp b/src/game.cpp index 50a355d59638d..77f1439c26488 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -128,6 +128,18 @@ bool is_valid_in_w_terrain(int x, int y) return x >= 0 && x < TERRAIN_WINDOW_WIDTH && y >= 0 && y < TERRAIN_WINDOW_HEIGHT; } +/* + * case insensitive string::find( string::findstr ). findstr must be lowercased + */ +bool lcmatch(const std::string &str, const std::string &findstr) +{ + std::string ret = ""; + ret.reserve( str.size() ); + transform( str.begin(), str.end(), std::back_inserter(ret), tolower ); + return ( (int)ret.find( findstr ) != -1 ); +} + + // This is the main game set-up process. game::game() : map_ptr( new map() ), @@ -8982,7 +8994,6 @@ tripoint game::look_around( WINDOW *w_info, const tripoint &start_point, return tripoint( INT_MIN, INT_MIN, INT_MIN ); } -bool lcmatch(const std::string &str, const std::string &findstr); // ui.cpp bool game::list_items_match(const item *item, std::string sPattern) { diff --git a/src/game.h b/src/game.h index b5ecdbd5b92d8..c7f0da9cd6a25 100644 --- a/src/game.h +++ b/src/game.h @@ -109,6 +109,9 @@ typedef std::vector< const std::list* > const_invslice; typedef std::vector< std::pair*, int> > indexed_invslice; typedef std::function item_filter; +// Helper functions +bool lcmatch(const std::string &str, const std::string &findstr); + class game { friend class editmap; diff --git a/src/input.cpp b/src/input.cpp index a6ba8aac9034d..0cf17c6d6f956 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -716,6 +716,7 @@ const std::string &input_context::handle_input() // Special help action if(action == "HELP_KEYBINDINGS") { display_help(); + redraw_windows(); return HELP_KEYBINDINGS; } @@ -1258,3 +1259,16 @@ std::string input_context::press_x(const std::string &action_id, const std::stri keyed << key_bound_suf; return keyed.str(); } + +void input_context::assign_windows(const std::vector& windows) +{ + context_windows = windows; +} + +void input_context::redraw_windows() +{ + for (auto win : context_windows) { + redrawwin(*win); + wrefresh(*win); + } +} diff --git a/src/input.h b/src/input.h index 19509d115fb04..da627ec931038 100644 --- a/src/input.h +++ b/src/input.h @@ -439,8 +439,8 @@ class input_context */ std::vector keys_bound_to(const std::string &action_id) const; private: - std::vector registered_actions; + public: const std::string &input_to_action(input_event &inp); private: @@ -475,6 +475,19 @@ class input_context * keybindings. */ void clear_conflicting_keybindings(const input_event &event); + + public: + /** + * Assigns windows that are displayed when context is used + */ + void assign_windows(const std::vector& windows); + /** + * Redraws all assigned windows + */ + void redraw_windows(); + private: + std::vector context_windows; + }; /** diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index 8896c26665dcf..2ba7ec8fab35e 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -65,8 +65,6 @@ int set_description(WINDOW *w, player *u, character_type type, int &points); void save_template(player *u); -bool lcmatch(const std::string &str, const std::string &findstr); // ui.cpp - void Character::pick_name(bool bUseDefault) { if (bUseDefault && OPTIONS["DEF_CHAR_NAME"]) { @@ -588,6 +586,9 @@ int set_stats(WINDOW *w, player *u, int &points) int read_spd; WINDOW *w_description = newwin(8, FULL_SCREEN_WIDTH - iSecondColumn - 1, 6 + getbegy(w), iSecondColumn + getbegx(w)); + + ctxt.assign_windows({&w, &w_description}); + // There is no map loaded currently, so any access to the map will // fail (player::suffer, called from player::reset_stats), might access // the map: @@ -839,6 +840,7 @@ int set_traits(WINDOW *w, player *u, int &points, int max_trait_points) ctxt.register_action("PREV_TAB"); ctxt.register_action("NEXT_TAB"); ctxt.register_action("HELP_KEYBINDINGS"); + ctxt.assign_windows({&w, &w_description}); do { mvwprintz(w, 3, 2, c_ltgray, _("Points left:%4d "), points); @@ -1071,6 +1073,7 @@ int set_profession(WINDOW *w, player *u, int &points) ctxt.register_action("SORT"); ctxt.register_action("HELP_KEYBINDINGS"); ctxt.register_action("FILTER"); + ctxt.assign_windows({&w, &w_description, &w_items, &w_genderswap}); bool recalc_profs = true; int profs_length = 0; @@ -1360,6 +1363,7 @@ int set_skills(WINDOW *w, player *u, int &points) ctxt.register_action("PREV_TAB"); ctxt.register_action("NEXT_TAB"); ctxt.register_action("HELP_KEYBINDINGS"); + ctxt.assign_windows({&w, &w_description}); do { mvwprintz(w, 3, 2, c_ltgray, _("Points left:%4d "), points); @@ -1522,6 +1526,7 @@ int set_scenario(WINDOW *w, player *u, int &points) ctxt.register_action("SORT"); ctxt.register_action("HELP_KEYBINDINGS"); ctxt.register_action("FILTER"); + ctxt.assign_windows({&w, &w_description, &w_profession, &w_location, &w_flags}); bool recalc_scens = true; int scens_length = 0; @@ -1811,6 +1816,8 @@ int set_description(WINDOW *w, player *u, character_type type, int &points) ctxt.register_action("REROLL_CHARACTER"); ctxt.register_action("REROLL_CHARACTER_WITH_SCENARIO"); ctxt.register_action("ANY_INPUT"); + ctxt.assign_windows({&w, &w_name, + &w_gender, &w_location, &w_stats, &w_traits, &w_scenario, &w_profession, &w_skills, &w_guide}); uimenu select_location; select_location.text = _("Select a starting location."); diff --git a/src/overmap.cpp b/src/overmap.cpp index ff4b9ac979a91..0bd4a8615e478 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -999,7 +999,6 @@ void overmap::delete_note(int const x, int const y, int const z) add_note(x, y, z, std::string {}); } -extern bool lcmatch(const std::string& text, const std::string& pattern); std::vector overmap::find_notes(int const z, std::string const &text) { std::vector note_locations; diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index 3872840045dcc..17dd6c78aa2d1 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -754,7 +754,6 @@ void overmapbuffer::despawn_monster(const monster &critter) om.monster_map.insert( std::make_pair( sm, critter ) ); } -extern bool lcmatch(const std::string& text, const std::string& pattern); overmapbuffer::t_notes_vector overmapbuffer::get_notes(int z, const std::string* pattern) { t_notes_vector result; diff --git a/src/player.cpp b/src/player.cpp index 9f4d231166eb8..ce6ea56fa80d2 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2585,6 +2585,11 @@ Strength - 4; Dexterity - 4; Intelligence - 4; Perception - 4")); ctxt.register_action("QUIT"); ctxt.register_action("CONFIRM", _("Toggle skill training")); ctxt.register_action("HELP_KEYBINDINGS"); + ctxt.assign_windows({&w_grid_top, &w_grid_skill, &w_grid_effect, &w_grid_trait, + &w_tip, &w_stats, &w_traits, &w_encumb, &w_effects, &w_speed, &w_skills, &w_info, + }); + + std::string action; std::string help_msg = string_format(_("Press %s for help."), ctxt.get_desc("HELP_KEYBINDINGS").c_str()); diff --git a/src/ui.cpp b/src/ui.cpp index dd46ab3f3dc52..d6cba2a931b40 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -194,17 +194,6 @@ void uimenu::init() hotkeys = DEFAULT_HOTKEYS; } -/* - * case insensitive string::find( string::findstr ). findstr must be lowercased - */ -bool lcmatch(const std::string &str, const std::string &findstr) -{ - std::string ret = ""; - ret.reserve( str.size() ); - transform( str.begin(), str.end(), std::back_inserter(ret), tolower ); - return ( (int)ret.find( findstr ) != -1 ); -} - /* * repopulate filtered entries list (fentries) and set fselected accordingly */ @@ -907,4 +896,3 @@ void pointmenu_cb::refresh( uimenu *menu ) { menu->redraw( false ); menu->show(); } - diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index 12aada249e677..baa748b4f1c91 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -36,7 +36,16 @@ const skill_id skill_mechanics( "mechanics" ); * Creates a blank veh_interact window. */ veh_interact::veh_interact () - : main_context("VEH_INTERACT") + : w_grid(nullptr) + , w_mode(nullptr) + , w_msg(nullptr) + , w_disp(nullptr) + , w_parts(nullptr) + , w_stats(nullptr) + , w_list(nullptr) + , w_details(nullptr) + , w_name(nullptr) + , main_context("VEH_INTERACT") { cpart = -1; ddx = 0; @@ -76,6 +85,10 @@ veh_interact::veh_interact () main_context.register_action("NEXT_TAB"); main_context.register_action("CONFIRM"); main_context.register_action("HELP_KEYBINDINGS"); + main_context.register_action("FILTER"); + + main_context.assign_windows({&w_grid, &w_mode, &w_msg, &w_disp, + &w_parts, &w_stats, &w_list, &w_details, &w_name}); } /** @@ -291,6 +304,7 @@ void veh_interact::do_main_loop() } else if (action == "PREV_TAB") { move_fuel_cursor(-1); } + if (sel_cmd != ' ') { finish = true; } @@ -762,6 +776,17 @@ void veh_interact::do_install() int pos = 0; size_t tab = 0; + + std::string sFilter; + std::function user_filter = [&](const vpart_info *p) { + return lcmatch(p->name, sFilter); + }; + + std::function part_filter = [&](const vpart_info *p) { + return user_filter(p) && tab_filters[tab](p); + }; + + while (true) { display_list(pos, tab_vparts, 2); @@ -824,9 +849,15 @@ void veh_interact::do_install() tab = ( tab < tab_list.size() - 1 ) ? tab + 1 : 0; } - copy_if(can_mount.begin(), can_mount.end(), back_inserter(tab_vparts), tab_filters[tab]); - } - else { + copy_if(can_mount.begin(), can_mount.end(), back_inserter(tab_vparts), part_filter); + } else if (action == "FILTER") { + sFilter = string_input_popup(_("Name filter:"), 55, sFilter, + _("UP: history, CTRL-U clear line, ESC: abort, ENTER: save"), "veh_part_filter", 256); + main_context.redraw_windows(); + pos = 0; + tab_vparts.clear(); + copy_if(can_mount.begin(), can_mount.end(), back_inserter(tab_vparts), part_filter); + } else { move_in_list(pos, action, tab_vparts.size(), 2); } } @@ -841,6 +872,7 @@ void veh_interact::do_install() display_name(); } + bool veh_interact::move_in_list(int &pos, const std::string &action, const int size, const int header) const { int lines_per_page = page_size - header; diff --git a/src/worldfactory.cpp b/src/worldfactory.cpp index 053b30ebecbdd..f40e02b00d054 100644 --- a/src/worldfactory.cpp +++ b/src/worldfactory.cpp @@ -460,6 +460,7 @@ WORLDPTR worldfactory::pick_world( bool show_prompt ) ctxt.register_action("NEXT_TAB"); ctxt.register_action("PREV_TAB"); ctxt.register_action("CONFIRM"); + ctxt.assign_windows({&w_worlds_border, &w_worlds_tooltip, &w_worlds_header, &w_worlds}); std::stringstream sTemp; @@ -648,6 +649,9 @@ int worldfactory::show_worldgen_tab_options(WINDOW *win, WORLDPTR world) ctxt.register_action("QUIT"); ctxt.register_action("NEXT_TAB"); ctxt.register_action("PREV_TAB"); + + ctxt.assign_windows({&win, &w_options, &w_options_tooltip, &w_options_header}); + int iStartPos = 0; int iCurrentLine = 0; @@ -907,6 +911,8 @@ int worldfactory::show_worldgen_tab_modselection(WINDOW *win, WORLDPTR world) FULL_SCREEN_WIDTH / 2 + 2 + iOffsetX); w_description = newwin(4, FULL_SCREEN_WIDTH - 2, 19 + iOffsetY, 1 + iOffsetX); + ctxt.assign_windows({&win, &w_header1, &w_header2, &w_shift, &w_list, &w_active, &w_description}); + draw_modselection_borders(win, &ctxt); std::vector headers; headers.push_back(_("Mod List")); @@ -1203,6 +1209,7 @@ int worldfactory::show_worldgen_tab_confirm(WINDOW *win, WORLDPTR world) ctxt.register_action("NEXT_TAB"); ctxt.register_action("PREV_TAB"); ctxt.register_action("PICK_RANDOM_WORLDNAME"); + ctxt.assign_windows({&win, &w_confirmation}); std::string worldname = world->world_name; do {