Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CR] Filter in vehicle menu for part installation #13341

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/catacurse.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/construction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,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 {
Expand Down
3 changes: 0 additions & 3 deletions src/crafting_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,9 +666,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<typename T>
bool lcmatch_any( const std::vector< std::vector<T> > &list_of_list, const std::string &filter )
{
Expand Down
20 changes: 20 additions & 0 deletions src/cursesport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,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;
}

Expand Down Expand Up @@ -618,6 +625,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++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of repeating the loop, why not call clearok?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it doesn't work.

clearok updates stdscr without touching win and I don't know if it's intended or not, but calling it doesn't fix black screen issues, while looping does.

(Oh, there's also a problem with clearok that its proper declaration is int clearok(WINDOW *win, bool bf);, not clearok(WINDOW *win) - but since veh_interact.cpp doesn't call it, I left it as is)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clearok updates stdscr without touching win and I don't know if it's intended or not, but calling it doesn't fix black screen issues, while looping does.

I did not see that, it looks like a bug. It's only used inside of wclear, which in turn is only used by clear in cursesport.cpp, it's a mess and it's probably not worth touching it.

The implementation of redrawwin is fine.

win->line[i].touched = true;
}
return 1;
}


//gets the max x of a window (the width)
int getmaxx(WINDOW *win)
{
Expand Down
12 changes: 12 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some specific reason why you moved this function around? game.cpp isn't really a good place for it, it has nothing to do with the game itself.

While ui.cpp may not be the best, it kind of fits there as it is mostly used for UI related stuff. Alternatively, it could be in in output.cpp or in catacharset.cpp (the function is btw. not Unicode-compatible).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved declaration to game.h so every second .cpp file would stop redeclaring it. And since it was moved to game.h for that, it might be defined in game.cpp as well.

I originally moved it to ui.h, but most files that used the function didn't include ui.h so it was not that much better(which I forgot to uninclude - it doesn't make sense to include entire ui.h for simple lcmatch). I din't find general helper functions header or file so moved to game.h which is included everywhere

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Because it's already included everywhere" is pretty much the worst reason to put a function in a particular file, the fact that everything includes game.h already is a major problem that we're trying to fix, and this makes the code go the wrong way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it doesn't feel like UI. It's string function. Should I make new header or there more appropriate header?

{
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() ),
Expand Down
3 changes: 3 additions & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ typedef std::vector< const std::list<item>* > const_invslice;
typedef std::vector< std::pair<std::list<item>*, int> > indexed_invslice;
typedef std::function<bool(const item &)> item_filter;

// Helper functions
bool lcmatch(const std::string &str, const std::string &findstr);

class game
{
friend class editmap;
Expand Down
16 changes: 15 additions & 1 deletion src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ const std::string &input_context::handle_input()
// Special help action
if(action == "HELP_KEYBINDINGS") {
display_help();
redraw_windows();
return HELP_KEYBINDINGS;
}

Expand Down Expand Up @@ -1281,6 +1282,19 @@ std::string input_context::press_x(const std::string &action_id, const std::stri
return keyed.str();
}

void input_context::assign_windows(const std::vector<WINDOW *const*>& windows)
{
context_windows = windows;
}

void input_context::redraw_windows()
{
for (auto win : context_windows) {
redrawwin(*win);
wrefresh(*win);
}
}

void input_context::set_iso(bool mode) {
iso_mode = mode;
}
}
15 changes: 14 additions & 1 deletion src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ class input_context

void set_iso(bool mode = true);
private:

std::vector<std::string> registered_actions;

public:
const std::string &input_to_action(input_event &inp);
private:
Expand Down Expand Up @@ -478,6 +478,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<WINDOW*const*>& windows);
/**
* Redraws all assigned windows
*/
void redraw_windows();
private:
std::vector<WINDOW*const*> context_windows;

};

/**
Expand Down
11 changes: 9 additions & 2 deletions src/newcharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,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"]) {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -842,6 +843,7 @@ int set_traits(WINDOW *w, player *u, int &points, int max_trait_points)
ctxt.register_action("NEXT_TAB");
ctxt.register_action("HELP_KEYBINDINGS");
ctxt.register_action("QUIT");
ctxt.assign_windows({&w, &w_description});

do {
mvwprintz(w, 3, 2, c_ltgray, _("Points left:%4d "), points);
Expand Down Expand Up @@ -1076,6 +1078,7 @@ int set_profession(WINDOW *w, player *u, int &points)
ctxt.register_action("HELP_KEYBINDINGS");
ctxt.register_action("FILTER");
ctxt.register_action("QUIT");
ctxt.assign_windows({&w, &w_description, &w_items, &w_genderswap});

bool recalc_profs = true;
int profs_length = 0;
Expand Down Expand Up @@ -1370,6 +1373,7 @@ int set_skills(WINDOW *w, player *u, int &points)
ctxt.register_action("NEXT_TAB");
ctxt.register_action("HELP_KEYBINDINGS");
ctxt.register_action("QUIT");
ctxt.assign_windows({&w, &w_description});

do {
mvwprintz(w, 3, 2, c_ltgray, _("Points left:%4d "), points);
Expand Down Expand Up @@ -1600,6 +1604,7 @@ int set_scenario(WINDOW *w, player *u, int &points)
ctxt.register_action("HELP_KEYBINDINGS");
ctxt.register_action("FILTER");
ctxt.register_action("QUIT");
ctxt.assign_windows({&w, &w_description, &w_profession, &w_location, &w_flags});

bool recalc_scens = true;
int scens_length = 0;
Expand Down Expand Up @@ -1892,6 +1897,8 @@ int set_description(WINDOW *w, player *u, character_type type, int &points)
ctxt.register_action("REROLL_CHARACTER_WITH_SCENARIO");
ctxt.register_action("ANY_INPUT");
ctxt.register_action("QUIT");
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.");
Expand Down
1 change: 0 additions & 1 deletion src/overmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,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<point> overmap::find_notes(int const z, std::string const &text)
{
std::vector<point> note_locations;
Expand Down
1 change: 0 additions & 1 deletion src/overmapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2595,6 +2595,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());
Expand Down
12 changes: 0 additions & 12 deletions src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,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
*/
Expand Down Expand Up @@ -915,4 +904,3 @@ void pointmenu_cb::refresh( uimenu *menu ) {
menu->redraw( false );
menu->show();
}

40 changes: 36 additions & 4 deletions src/veh_interact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,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;
Expand Down Expand Up @@ -78,6 +87,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});
}

/**
Expand Down Expand Up @@ -293,6 +306,7 @@ void veh_interact::do_main_loop()
} else if (action == "PREV_TAB") {
move_fuel_cursor(-1);
}

if (sel_cmd != ' ') {
finish = true;
}
Expand Down Expand Up @@ -811,6 +825,17 @@ void veh_interact::do_install()

int pos = 0;
size_t tab = 0;

std::string sFilter;
std::function<bool(const vpart_info*)> user_filter = [&](const vpart_info *p) {
return lcmatch(p->name, sFilter);
};

std::function<bool(const vpart_info*)> part_filter = [&](const vpart_info *p) {
return user_filter(p) && tab_filters[tab](p);
};


while (true) {
display_list(pos, tab_vparts, 2);

Expand Down Expand Up @@ -873,9 +898,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);
}
}
Expand All @@ -890,6 +921,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;
Expand Down
7 changes: 7 additions & 0 deletions src/worldfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,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;

Expand Down Expand Up @@ -642,6 +643,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;

Expand Down Expand Up @@ -901,6 +905,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<std::string> headers;
headers.push_back(_("Mod List"));
Expand Down Expand Up @@ -1197,6 +1203,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 {
Expand Down