Add-ons manager: handle the selected add-on changing in small-screen mode

Fix another instance of issue #3059, where code assumes that all parts of the
add-ons manager's UI are accessible, an assumption that fails when the dialog
uses a stacked widget to handle small window sizes.

The up and down arrow keys select the previous or next add-on in the list,
even when the small-window layout is hiding the list. That feels like a feature
rather than a bug, as it's useful and an understandable UX; however it needs
the fix in this commit so that on_addon_select() doesn't throw an exception
and close the dialog. The new code is the same as the fix that 050feb623b
applied to on_selected_version_change, traversing the stacked widget to get the
info.

(cherry picked from commit 6a72b2e511)
This commit is contained in:
Steve Cotton 2022-02-05 04:51:36 +01:00 committed by Steve Cotton
parent c4a7fce80a
commit 6d6d38e5bb
2 changed files with 11 additions and 7 deletions

View file

@ -1,5 +1,6 @@
## Version 1.17.0+dev
### Add-ons client
* Fixed: using the up or down arrow keys in small-screen mode returned to the title screen (issue #6485)
### Add-ons server
### Campaigns
* Delfadors Memoirs

View file

@ -688,7 +688,8 @@ void addon_manager::apply_filters()
// In the small-screen layout, the text_box for the filter keeps keyboard focus even when the
// details panel is visible, which means this can be called when the list isn't visible. That
// causes problems both because find_widget can throw exceptions, but also because changing the
// filters can trigger on_addon_select and thus affect which add-on's details are shown.
// filters can hide the currently-shown add-on, triggering a different one to be selected in a
// way that would seem random unless the user realised that they were typing into a filter box.
//
// Quick workaround is to not process the new filter if the list isn't visible.
auto list = find_widget<addon_list>(get_window(), "addons", false, false);
@ -971,17 +972,19 @@ static std::string format_addon_time(std::time_t time)
void addon_manager::on_addon_select()
{
const addon_info* info = find_widget<addon_list>(get_window(), "addons", false).get_selected_addon();
widget* parent = get_window();
widget* parent_of_addons_list = parent;
if(stacked_widget* stk = find_widget<stacked_widget>(get_window(), "main_stack", false, false)) {
parent = stk->get_layer_grid(1);
parent_of_addons_list = stk->get_layer_grid(0);
}
const addon_info* info = find_widget<addon_list>(parent_of_addons_list, "addons", false).get_selected_addon();
if(info == nullptr) {
return;
}
widget* parent = get_window();
if(stacked_widget* stk = find_widget<stacked_widget>(get_window(), "main_stack", false, false)) {
parent = stk->get_layer_grid(1);
}
find_widget<drawing>(parent, "image", false).set_label(info->display_icon());
find_widget<styled_widget>(parent, "title", false).set_label(info->display_title_translated_or_original());