More work on the add-on list widget

This commit is contained in:
Jyrki Vesterinen 2017-01-26 20:31:53 +02:00
parent 4b1ca8a50a
commit e158c63a95
4 changed files with 107 additions and 77 deletions

View file

@ -151,13 +151,6 @@ namespace {
}
return it->second;
}
inline const addon_info& addon_at(const std::string& id, const addons_list& addons)
{
addons_list::const_iterator it = addons.find(id);
assert(it != addons.end());
return it->second;
}
}
REGISTER_DIALOG(addon_manager)
@ -169,20 +162,29 @@ addon_manager::addon_manager(addons_client& client)
, client_(client)
, addons_()
, tracking_info_()
, ids_()
{
}
void addon_manager::on_filtertext_changed(text_box_base* textbox, const std::string& text)
{
listbox& addons = find_widget<listbox>(textbox->get_window(), "addons", true);
addon_list& addons = find_widget<addon_list>(textbox->get_window(), "addons", true);
filter_transform filter(utils::split(text, ' '));
boost::dynamic_bitset<> res;
for(const auto& child : cfg_.child_range("campaign"))
const config::const_child_itors& addon_cfgs = cfg_.child_range("campaign");
for(const auto& a : addons_)
{
res.push_back(filter(child));
const config& addon_cfg = *std::find_if(addon_cfgs.begin(), addon_cfgs.end(),
[&a](const config& cfg)
{
return cfg["name"] == a.first;
});
res.push_back(filter(addon_cfg));
}
addons.set_row_shown(res);
addons.set_addon_shown(res);
}
static std::string describe_status_verbose(const addon_tracking_info& state)
@ -253,14 +255,6 @@ void addon_manager::pre_show(window& window)
load_addon_list(window);
addon_list& list = find_widget<addon_list>(&window, "addons", false);
/*
list.register_sorting_option(0, [this](const int i) { return addon_at(ids_[i], addons_).title; });
list.register_sorting_option(1, [this](const int i) { return addon_at(ids_[i], addons_).author; });
list.register_sorting_option(2, [this](const int i) { return addon_at(ids_[i], addons_).size; });
list.register_sorting_option(3, [this](const int i) { return addon_at(ids_[i], addons_).downloads; });
list.register_sorting_option(4, [this](const int i) { return addon_at(ids_[i], addons_).type; });
*/
find_widget<text_box>(&window, "filter", false).set_text_changed_callback(
std::bind(&addon_manager::on_filtertext_changed, this, _1, _2));
@ -332,34 +326,14 @@ void addon_manager::load_addon_list(window& window)
addon_list& list = find_widget<addon_list>(&window, "addons", false);
list.set_addons(addons_);
ids_.clear();
for(const auto& a : addons_)
{
ids_.push_back(a.first);
const addon_info& info = addon_at(ids_.back(), addons_);
tracking_info_[info.id] = get_addon_tracking_info(info);
tracking_info_[a.first] = get_addon_tracking_info(a.second);
}
// TODO: wire up the install buttons in some way
}
unsigned int addon_manager::get_addon_index(listbox& addon_list, const std::string& id)
{
const addon_info& info = addon_at(id, addons_);
for(unsigned int i = 0u; i < addon_list.get_item_count(); ++i)
{
grid* row = addon_list.get_row_grid(i);
const label& name_label = find_widget<label>(row, "name", false);
if(name_label.get_label().base_str() == info.display_title())
{
return i;
}
}
return 0xFFFFFFFFu;
}
void addon_manager::options_button_callback(window& window)
{
// TODO
@ -377,18 +351,18 @@ void addon_manager::options_button_callback(window& window)
void addon_manager::install_selected_addon(window& window)
{
addon_list& addons = find_widget<addon_list>(&window, "addons", false);
const int index = addons.get_selected_row();
const addon_info* addon = addons.get_selected_addon();
if(index == -1) {
if(addon == nullptr) {
return;
}
install_addon(addon_at(ids_[index], addons_), window);
install_addon(*addon, window);
}
void addon_manager::install_addon(addon_info addon, window& window)
{
listbox& addon_listbox = find_widget<addon_list>(&window, "addons", false).get_listbox();
addon_list& addons = find_widget<addon_list>(&window, "addons", false);
config archive;
bool download_succeeded = client_.download_addon(archive, addon.id, addon.title);
if(download_succeeded)
@ -399,7 +373,7 @@ void addon_manager::install_addon(addon_info addon, window& window)
load_addon_list(window);
// Reselect the add-on.
addon_listbox.select_row(get_addon_index(addon_listbox, addon.id));
addons.select_addon(addon.id);
on_addon_select(window);
return;
@ -450,32 +424,30 @@ static std::string format_addon_time(time_t time)
void addon_manager::on_addon_select(window& window)
{
const int index = find_widget<addon_list>(&window, "addons", false).get_selected_row();
const addon_info* info = find_widget<addon_list>(&window, "addons", false).get_selected_addon();
if(index == -1) {
if(info == nullptr) {
return;
}
const addon_info& info = addon_at(ids_[index], addons_);
find_widget<drawing>(&window, "image", false).set_label(info->display_icon());
find_widget<drawing>(&window, "image", false).set_label(info.display_icon());
find_widget<styled_widget>(&window, "title", false).set_label(info.display_title());
find_widget<styled_widget>(&window, "description", false).set_label(info.description);
find_widget<styled_widget>(&window, "version", false).set_label(info.version.str());
find_widget<styled_widget>(&window, "author", false).set_label(info.author);
find_widget<styled_widget>(&window, "type", false).set_label(info.display_type());
find_widget<styled_widget>(&window, "title", false).set_label(info->display_title());
find_widget<styled_widget>(&window, "description", false).set_label(info->description);
find_widget<styled_widget>(&window, "version", false).set_label(info->version.str());
find_widget<styled_widget>(&window, "author", false).set_label(info->author);
find_widget<styled_widget>(&window, "type", false).set_label(info->display_type());
styled_widget& status = find_widget<styled_widget>(&window, "status", false);
status.set_label(describe_status_verbose(tracking_info_[info.id]));
status.set_label(describe_status_verbose(tracking_info_[info->id]));
status.set_use_markup(true);
find_widget<styled_widget>(&window, "size", false).set_label(size_display_string(info.size));
find_widget<styled_widget>(&window, "downloads", false).set_label(std::to_string(info.downloads));
find_widget<styled_widget>(&window, "created", false).set_label(format_addon_time(info.created));
find_widget<styled_widget>(&window, "updated", false).set_label(format_addon_time(info.updated));
find_widget<styled_widget>(&window, "size", false).set_label(size_display_string(info->size));
find_widget<styled_widget>(&window, "downloads", false).set_label(std::to_string(info->downloads));
find_widget<styled_widget>(&window, "created", false).set_label(format_addon_time(info->created));
find_widget<styled_widget>(&window, "updated", false).set_label(format_addon_time(info->updated));
const std::string& feedback_url = info.feedback_url;
const std::string& feedback_url = info->feedback_url;
if(!feedback_url.empty()) {
find_widget<stacked_widget>(&window, "feedback_stack", false).select_layer(1);
@ -484,7 +456,7 @@ void addon_manager::on_addon_select(window& window)
find_widget<stacked_widget>(&window, "feedback_stack", false).select_layer(0);
}
bool installed = is_installed_addon_status(tracking_info_[info.id].state);
bool installed = is_installed_addon_status(tracking_info_[info->id].state);
find_widget<button>(&window, "install", false).set_active(!installed);
find_widget<button>(&window, "uninstall", false).set_active(installed);

View file

@ -54,8 +54,6 @@ private:
void load_addon_list(window& window);
unsigned int get_addon_index(listbox& addon_list, const std::string& id);
/** Config which contains the list with the campaigns. */
config cfg_;
@ -70,8 +68,6 @@ private:
addons_tracking_list tracking_info_;
std::vector<std::string> ids_;
void install_selected_addon(window& window);
void install_addon(addon_info addon, window& window);
void browse_url_callback(text_box& url_box);

View file

@ -24,6 +24,7 @@
#include "gui/widgets/settings.hpp"
#include "gui/widgets/stacked_widget.hpp"
#include "wml_exception.hpp"
#include <algorithm>
namespace gui2
{
@ -103,10 +104,14 @@ void addon_list::set_addons(const addons_list& addons)
listbox& list = get_listbox();
list.clear();
addon_vector_.clear();
for(const auto& a : addons) {
const addon_info& addon = a.second;
addon_tracking_info tracking_info = get_addon_tracking_info(addon);
addon_vector_.push_back(&addon);
std::map<std::string, string_map> data;
string_map item;
@ -156,6 +161,54 @@ void addon_list::set_addons(const addons_list& addons)
}
}
const addon_info* addon_list::get_selected_addon() const
{
const listbox& list = find_widget<const listbox>(&get_grid(), "addons", false);
int index = list.get_selected_row();
if(index == -1)
{
return nullptr;
}
return addon_vector_.at(index);
}
void addon_list::select_addon(const std::string& id)
{
listbox& list = get_listbox();
const addon_info& info = **std::find_if(addon_vector_.begin(), addon_vector_.end(),
[&id](const addon_info* a)
{
return a->id == id;
});
for(unsigned int i = 0u; i < list.get_item_count(); ++i)
{
grid* row = list.get_row_grid(i);
const label& name_label = find_widget<label>(row, "name", false);
if(name_label.get_label().base_str() == info.display_title())
{
list.select_row(i);
}
}
}
listbox& addon_list::get_listbox()
{
return find_widget<listbox>(&get_grid(), "addons", false);
}
void addon_list::finalize_setup()
{
listbox& list = get_listbox();
list.register_sorting_option(0, [this](const int i) { return addon_vector_[i]->title; });
list.register_sorting_option(1, [this](const int i) { return addon_vector_[i]->author; });
list.register_sorting_option(2, [this](const int i) { return addon_vector_[i]->size; });
list.register_sorting_option(3, [this](const int i) { return addon_vector_[i]->downloads; });
list.register_sorting_option(4, [this](const int i) { return addon_vector_[i]->type; });
}
addon_list_definition::addon_list_definition(const config& cfg) :
styled_widget_definition(cfg)
{
@ -223,6 +276,8 @@ widget* builder_addon_list::build() const
widget->set_install_status_visibility(install_status_visibility_);
widget->set_install_buttons_visibility(install_buttons_visibility_);
widget->finalize_setup();
return widget;
}

View file

@ -16,11 +16,12 @@
#include "addon/info.hpp"
#include "addon/state.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/widgets/container_base.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/widget.hpp"
#include <boost/dynamic_bitset.hpp>
#include <string>
#include <vector>
namespace gui2
{
@ -37,6 +38,7 @@ class addon_list : public container_base
public:
addon_list()
: container_base(1)
, addon_vector_()
, install_status_visibility_(visibility::visible)
, install_buttons_visibility_(visibility::invisible)
{}
@ -50,17 +52,16 @@ public:
get_listbox().set_callback_value_change(callback);
}
/** Returns the index of the selected row. */
int get_selected_row() const
{
const listbox& list = find_widget<const listbox>(&get_grid(), "addons", false);
return list.get_selected_row();
}
/** Returns the selected add-on. */
const addon_info* get_selected_addon() const;
/** Returns the underlying list box. */
listbox& get_listbox()
/** Selects the add-on with the given ID. */
void select_addon(const std::string& id);
/** Filters which add-ons are visible. 1 = visible, 0 = hidden. */
void set_addon_shown(boost::dynamic_bitset<>& shown)
{
return find_widget<listbox>(&get_grid(), "addons", false);
get_listbox().set_row_shown(shown);
}
/** Changes the color of an add-on state string (installed, outdated, etc.)
@ -99,11 +100,17 @@ public:
}
private:
std::vector<const addon_info*> addon_vector_;
visibility install_status_visibility_;
visibility install_buttons_visibility_;
static std::string describe_status(const addon_tracking_info& info);
/** Returns the underlying list box. */
listbox& get_listbox();
void finalize_setup();
/** See @ref control::get_control_type. */
const std::string& get_control_type() const override
{