GUI2/Preferences: refactored how hotkey categories are handled
Constitutes a further refinement of a688ab77b9
.
Instead of getting a list of categories and filtering out those without any hotkeys (custom WML ones,
for example), we generate a set of categories from the list of visible hotkeys when we set up the list.
This ensures we only ever have matching categories for the hotkeys we're seeing and removes the need
for extra global bookkeeping in the category code.
This also ensures the category list is reconstructed when resetting hotkeys. I don't know how categories
could have appeared/disappeared after resetting (the old code should be safe), but this makes sure it
will never be an issue since when visible_hotkeys is changed, so is visible_categories.
This commit is contained in:
parent
58c9d4feae
commit
023bdb7142
3 changed files with 57 additions and 51 deletions
|
@ -206,6 +206,7 @@
|
|||
id = "lbl_is_game"
|
||||
definition = "default_small"
|
||||
linked_group = "hotkeys_col_type"
|
||||
use_markup = true
|
||||
[/label]
|
||||
[/column]
|
||||
|
||||
|
@ -217,6 +218,7 @@
|
|||
id = "lbl_is_editor"
|
||||
definition = "default"
|
||||
linked_group = "hotkeys_col_type"
|
||||
use_markup = true
|
||||
[/label]
|
||||
[/column]
|
||||
|
||||
|
@ -228,6 +230,7 @@
|
|||
id = "lbl_is_mainmenu"
|
||||
definition = "default"
|
||||
linked_group = "hotkeys_col_type"
|
||||
use_markup = true
|
||||
[/label]
|
||||
[/column]
|
||||
[/row]
|
||||
|
|
|
@ -114,15 +114,9 @@ preferences_dialog::preferences_dialog(const PREFERENCE_VIEW initial_view)
|
|||
, last_selected_item_(0)
|
||||
, accl_speeds_({0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 8, 16})
|
||||
, visible_hotkeys_()
|
||||
, cat_names_()
|
||||
, visible_categories_()
|
||||
, initial_index_(pef_view_map[initial_view])
|
||||
{
|
||||
for(const auto& name : hotkey::get_category_names()) {
|
||||
// Don't include categories with no hotkeys
|
||||
if(!hotkey::get_hotkeys_by_category(name.first).empty()) {
|
||||
cat_names_[name.first] = t_string(name.second, "wesnoth-lib");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to refresh resolution list
|
||||
|
@ -734,15 +728,7 @@ void preferences_dialog::post_build(window& window)
|
|||
// HOTKEYS PANEL
|
||||
//
|
||||
|
||||
std::vector<config> hotkey_category_entries;
|
||||
for(const auto& name : cat_names_) {
|
||||
hotkey_category_entries.emplace_back("label", name.second, "checkbox", false);
|
||||
}
|
||||
|
||||
multimenu_button& hotkey_menu = find_widget<multimenu_button>(&window, "hotkey_category_menu", false);
|
||||
|
||||
hotkey_menu.set_values(hotkey_category_entries);
|
||||
|
||||
connect_signal_notify_modified(hotkey_menu,
|
||||
std::bind(&preferences_dialog::hotkey_filter_callback, this));
|
||||
|
||||
|
@ -784,56 +770,74 @@ void preferences_dialog::post_build(window& window)
|
|||
|
||||
listbox& preferences_dialog::setup_hotkey_list()
|
||||
{
|
||||
const std::string& default_icon = "misc/empty.png~CROP(0,0,15,15)";
|
||||
|
||||
std::map<std::string, string_map> row_data;
|
||||
|
||||
t_string& row_icon = row_data["img_icon"]["label"];
|
||||
t_string& row_icon = row_data["img_icon"]["label"];
|
||||
t_string& row_action = row_data["lbl_desc"]["label"];
|
||||
t_string& row_hotkey = row_data["lbl_hotkey"]["label"];
|
||||
|
||||
t_string& row_is_g = row_data["lbl_is_game"]["label"];
|
||||
t_string& row_is_g_markup = row_data["lbl_is_game"]["use_markup"];
|
||||
t_string& row_is_e = row_data["lbl_is_editor"]["label"];
|
||||
t_string& row_is_e_markup = row_data["lbl_is_editor"]["use_markup"];
|
||||
t_string& row_is_m = row_data["lbl_is_mainmenu"]["label"];
|
||||
t_string& row_is_m_markup = row_data["lbl_is_mainmenu"]["use_markup"];
|
||||
t_string& row_is_g = row_data["lbl_is_game"]["label"];
|
||||
t_string& row_is_e = row_data["lbl_is_editor"]["label"];
|
||||
t_string& row_is_m = row_data["lbl_is_mainmenu"]["label"];
|
||||
|
||||
listbox& hotkey_list = find_widget<listbox>(get_window(), "list_hotkeys", false);
|
||||
|
||||
hotkey_list.clear();
|
||||
visible_hotkeys_.clear();
|
||||
visible_categories_.clear();
|
||||
|
||||
//
|
||||
// Main hotkeys list
|
||||
//
|
||||
|
||||
// These translated initials should match those used in data/gui/window/preferences/02_hotkeys.cfg
|
||||
std::string text_game_feature_on = "<span color='#0f0'>" + _("game_hotkeys^G") + "</span>";
|
||||
std::string text_editor_feature_on = "<span color='#0f0'>" + _("editor_hotkeys^E") + "</span>";
|
||||
std::string text_mainmenu_feature_on = "<span color='#0f0'>" + _("mainmenu_hotkeys^M") + "</span>";
|
||||
const std::string gh = "<span color='#0f0'>" + _("game_hotkeys^G") + "</span>";
|
||||
const std::string eh = "<span color='#0f0'>" + _("editor_hotkeys^E") + "</span>";
|
||||
const std::string mh = "<span color='#0f0'>" + _("mainmenu_hotkeys^M") + "</span>";
|
||||
|
||||
for(const auto& hotkey_item : hotkey::get_hotkey_commands()) {
|
||||
if(hotkey_item.hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visible_hotkeys_.push_back(&hotkey_item);
|
||||
visible_categories_.insert(hotkey_item.category);
|
||||
|
||||
if(filesystem::file_exists(game_config::path + "/images/icons/action/" + hotkey_item.id + "_25.png")) {
|
||||
row_icon = "icons/action/" + hotkey_item.id + "_25.png~CROP(3,3,18,18)";
|
||||
} else {
|
||||
row_icon = default_icon;
|
||||
}
|
||||
|
||||
row_action = hotkey_item.description;
|
||||
row_hotkey = hotkey::get_names(hotkey_item.id);
|
||||
|
||||
row_is_g = hotkey_item.scope[hotkey::SCOPE_GAME] ? text_game_feature_on : "";
|
||||
row_is_g_markup = "true";
|
||||
row_is_e = hotkey_item.scope[hotkey::SCOPE_EDITOR] ? text_editor_feature_on : "";
|
||||
row_is_e_markup = "true";
|
||||
row_is_m = hotkey_item.scope[hotkey::SCOPE_MAIN_MENU] ? text_mainmenu_feature_on : "";
|
||||
row_is_m_markup = "true";
|
||||
if(hotkey_item.scope[hotkey::SCOPE_GAME]) {
|
||||
row_is_g = gh;
|
||||
}
|
||||
|
||||
if(hotkey_item.scope[hotkey::SCOPE_EDITOR]) {
|
||||
row_is_e = eh;
|
||||
}
|
||||
|
||||
if(hotkey_item.scope[hotkey::SCOPE_MAIN_MENU]) {
|
||||
row_is_m = mh;
|
||||
}
|
||||
|
||||
hotkey_list.add_row(row_data);
|
||||
}
|
||||
|
||||
//
|
||||
// Filter options
|
||||
//
|
||||
|
||||
const auto& cat_names = hotkey::get_category_names();
|
||||
std::vector<config> filter_ops;
|
||||
|
||||
for(const hotkey::HOTKEY_CATEGORY& cat : visible_categories_) {
|
||||
filter_ops.emplace_back("label", t_string{cat_names.at(cat), "wesnoth-lib"}, "checkbox", false);
|
||||
}
|
||||
|
||||
find_widget<multimenu_button>(get_window(), "hotkey_category_menu", false).set_values(filter_ops);
|
||||
|
||||
return hotkey_list;
|
||||
}
|
||||
|
||||
|
@ -903,8 +907,6 @@ void preferences_dialog::default_hotkey_callback()
|
|||
// Set up the list again and reselect the default sorting option.
|
||||
listbox& hotkey_list = setup_hotkey_list();
|
||||
hotkey_list.set_active_sorting_option({0, sort_order::type::ascending}, true);
|
||||
|
||||
find_widget<multimenu_button>(get_window(), "hotkey_category_menu", false).reset_toggle_states();
|
||||
}
|
||||
|
||||
void preferences_dialog::remove_hotkey_callback(listbox& hotkeys)
|
||||
|
@ -930,39 +932,41 @@ void preferences_dialog::hotkey_filter_callback() const
|
|||
|
||||
std::string text = name_filter.get_value();
|
||||
|
||||
// Nothing selected. It means that *all* categories are shown.
|
||||
if(toggle_states.none()) {
|
||||
// Nothing selected. It means that *all* categories are shown.
|
||||
toggle_states = ~toggle_states;
|
||||
}
|
||||
|
||||
for(std::size_t h = 0; h < visible_hotkeys_.size(); ++h) {
|
||||
unsigned index = 0;
|
||||
|
||||
const std::string description = visible_hotkeys_[h]->description.str();
|
||||
|
||||
// Default to true if there is no filter text
|
||||
bool found = true;
|
||||
|
||||
if(!text.empty()) {
|
||||
const std::string description = visible_hotkeys_[h]->description.str();
|
||||
|
||||
for(const auto& word : utils::split(text, ' ')) {
|
||||
found = translation::ci_search(description, word);
|
||||
|
||||
// No match, we're excluding this hotkey
|
||||
if(!found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned cat_index = 0;
|
||||
|
||||
// Filter categories
|
||||
for(const auto& name : cat_names_) {
|
||||
if(visible_hotkeys_[h]->category == name.first) {
|
||||
for(const hotkey::HOTKEY_CATEGORY& cat : visible_categories_) {
|
||||
if(visible_hotkeys_[h]->category == cat) {
|
||||
break;
|
||||
} else {
|
||||
++index;
|
||||
++cat_index;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < toggle_states.size() && found) {
|
||||
res[h] = toggle_states[index];
|
||||
if(cat_index < toggle_states.size() && found) {
|
||||
res[h] = toggle_states[cat_index];
|
||||
} else {
|
||||
res[h] = false;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,6 @@ public:
|
|||
/** The display function -- see @ref modal_dialog for more information. */
|
||||
DEFINE_SIMPLE_DISPLAY_WRAPPER(preferences_dialog)
|
||||
|
||||
typedef std::vector<const hotkey::hotkey_command*> visible_hotkeys_t;
|
||||
|
||||
private:
|
||||
virtual const std::string& window_id() const override;
|
||||
|
||||
|
@ -125,9 +123,10 @@ private:
|
|||
int last_selected_item_;
|
||||
|
||||
std::vector<double> accl_speeds_;
|
||||
visible_hotkeys_t visible_hotkeys_;
|
||||
|
||||
std::map<hotkey::HOTKEY_CATEGORY, t_string> cat_names_;
|
||||
std::vector<const hotkey::hotkey_command*> visible_hotkeys_;
|
||||
|
||||
std::set<hotkey::HOTKEY_CATEGORY> visible_categories_;
|
||||
|
||||
// The page/tab index pairs for setting visible pages
|
||||
const std::pair<int, int>& initial_index_;
|
||||
|
|
Loading…
Add table
Reference in a new issue