Converted Statistics dialog to GUI2

This commit is contained in:
Charles Dang 2016-11-20 07:33:22 +11:00
parent 524f23db58
commit 049f067073
10 changed files with 989 additions and 400 deletions

View file

@ -0,0 +1,601 @@
#textdomain wesnoth-lib
###
### Definition of the window to display scenario or campaign statistics
###
#define _GUI_MAIN_STATS_LIST
[listbox]
id = "stats_list_main"
definition = "default"
horizontal_scrollbar_mode = "never"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
[grid]
[row]
[column]
grow_factor = 2
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "stat_type"
definition = "default"
linked_group = "type"
[/label]
[/column]
[column]
grow_factor = 2
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "stat_detail"
definition = "default_small"
linked_group = "detail"
[/label]
[/column]
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_grow = "true"
[image]
id = "cost_icon"
definition = "default"
label = "themes/gold.png"
[/image]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "stat_cost"
definition = "default_small"
linked_group = "cost"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
#enddef
#define _GUI_DAMAGE_STATS_LIST
[listbox]
id = "stats_list_damage"
definition = "default"
horizontal_scrollbar_mode = "never"
[header]
[row]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "top,bottom"
border_size = 5
[label]
definition = "default_small"
label = _ "Damage"
linked_group = "type"
[/label]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "top,bottom"
border_size = 5
[label]
definition = "default_small"
label = _ "Overall"
linked_group = "detail"
[/label]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "top,bottom"
border_size = 5
[label]
definition = "default_small"
label = _ "This Turn"
linked_group = "cost"
[/label]
[/column]
[/row]
[/header]
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
[grid]
[row]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "damage_type"
definition = "default"
linked_group = "type"
[/label]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "damage_overall"
definition = "default_small"
linked_group = "detail"
[/label]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "damage_this_turn"
definition = "default_small"
linked_group = "cost"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
#enddef
#define _GUI_UNIT_COUNT_LIST
[listbox]
id = "stats_list_units"
definition = "default"
has_minimum = "false"
horizontal_scrollbar_mode = "never"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
[grid]
[row]
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_grow = "true"
[image]
id = "unit_image"
definition = "default"
linked_group = "unit_image"
[/image]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "unit_name"
definition = "default_small"
linked_group = "unit_name"
[/label]
[/column]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
[label]
id = "unit_count"
definition = "default"
linked_group = "unit_count"
[/label]
[/column]
[column]
grow_factor = 0
[spacer]
width = 10
[/spacer]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
#enddef
#define _GUI_STATS_TAB_BAR
[toggle_panel]
linked_group = "tabs"
[grid]
[row]
{_GUI_STATS_TAB_PADDING}
[column]
grow_factor = 1
border = all
border_size = 5
[label]
id = "tab_label"
wrap = true
[/label]
[/column]
{_GUI_STATS_TAB_PADDING}
[/row]
[/grid]
[/toggle_panel]
#enddef
#define _GUI_STATS_TAB_PADDING
[column]
border = all
border_size = 5
[spacer]
width = 10
[/spacer]
[/column]
#enddef
[window]
id = "statistics_dialog"
description = "Statistics dialog."
[resolution]
definition = "default"
automatic_placement = "true"
vertical_placement = "center"
horizontal_placement = "center"
maximum_height = 500
[linked_group]
id = "tabs"
fixed_width = "true"
[/linked_group]
# Primary groups
[linked_group]
id = "type"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "detail"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "cost"
fixed_width = "true"
[/linked_group]
# Unit groups
[linked_group]
id = "unit_image"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "unit_name"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "unit_count"
fixed_width = "true"
[/linked_group]
[tooltip]
id = "tooltip"
[/tooltip]
[helptip]
id = "tooltip"
[/helptip]
[grid]
[row]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
id = "title"
definition = "title"
label = _ "Statistics"
[/label]
[/column]
[/row]
[row]
grow_factor = 0
[column]
horizontal_grow = "true"
[grid]
[row]
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_alignment = "left"
[menu_button]
id = "scenario_menu"
definition = "default"
[/menu_button]
[/column]
[column]
grow_factor = 1
border = all
border_size = 5
horizontal_alignment = "right"
[horizontal_listbox]
id = "tab_bar"
[list_definition]
[row]
[column]
{_GUI_STATS_TAB_BAR}
[/column]
[/row]
[/list_definition]
[list_data]
[row]
[column]
[widget]
id = "tab_label"
label = _ "Scenario"
[/widget]
[/column]
[/row]
[row]
[column]
[widget]
id = "tab_label"
label = _ "Campaign"
[/widget]
[/column]
[/row]
[/list_data]
[/horizontal_listbox]
[/column]
[/row]
[/grid]
[/column]
[/row]
[row]
grow_factor = 1
[column]
horizontal_grow = "true"
vertical_grow = "true"
[grid]
[row]
[column]
horizontal_grow = "true"
vertical_grow = "true"
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_grow = "true"
vertical_grow = "true"
{_GUI_MAIN_STATS_LIST}
[/column]
[/row]
[row]
grow_factor = 1
[column]
border = "all"
border_size = 5
horizontal_grow = "true"
vertical_grow = "true"
{_GUI_DAMAGE_STATS_LIST}
[/column]
[/row]
[/grid]
[/column]
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_grow = "true"
vertical_grow = "true"
{_GUI_UNIT_COUNT_LIST}
[/column]
[/row]
[/grid]
[/column]
[/row]
[row]
grow_factor = 0
[column]
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "cancel"
label = _ "Close"
[/button]
[/column]
[/row]
[/grid]
[/resolution]
[/window]
#undef _GUI_MAIN_STATS_LIST
#undef _GUI_DAMAGE_STATS_LIST
#undef _GUI_UNIT_COUNT_LIST
#undef _GUI_STATS_TAB_BAR
#undef _GUI_STATS_TAB_PADDING

View file

@ -646,6 +646,8 @@
<Unit filename="../../src/gui/dialogs/simple_item_selector.hpp" />
<Unit filename="../../src/gui/dialogs/sp_options_configure.cpp" />
<Unit filename="../../src/gui/dialogs/sp_options_configure.hpp" />
<Unit filename="../../src/gui/dialogs/statistics_dialog.cpp" />
<Unit filename="../../src/gui/dialogs/statistics_dialog.hpp" />
<Unit filename="../../src/gui/dialogs/theme_list.cpp" />
<Unit filename="../../src/gui/dialogs/theme_list.hpp" />
<Unit filename="../../src/gui/dialogs/tip.cpp" />
@ -1019,8 +1021,6 @@
<Unit filename="../../src/spirit_po/version.hpp" />
<Unit filename="../../src/statistics.cpp" />
<Unit filename="../../src/statistics.hpp" />
<Unit filename="../../src/statistics_dialog.cpp" />
<Unit filename="../../src/statistics_dialog.hpp" />
<Unit filename="../../src/storyscreen/controller.cpp" />
<Unit filename="../../src/storyscreen/controller.hpp" />
<Unit filename="../../src/storyscreen/interface.cpp" />

View file

@ -813,6 +813,7 @@ set(wesnoth-main_SRC
gui/dialogs/select_orb_colors.cpp
gui/dialogs/simple_item_selector.cpp
gui/dialogs/sp_options_configure.cpp
gui/dialogs/statistics_dialog.cpp
gui/dialogs/multiplayer/synced_choice_wait.cpp
gui/dialogs/theme_list.cpp
gui/dialogs/title_screen.cpp
@ -897,7 +898,6 @@ set(wesnoth-main_SRC
side_filter.cpp
game_initialization/singleplayer.cpp
statistics.cpp
statistics_dialog.cpp
storyscreen/controller.cpp
storyscreen/interface.cpp
storyscreen/part.cpp

View file

@ -412,6 +412,7 @@ wesnoth_sources = Split("""
gui/dialogs/select_orb_colors.cpp
gui/dialogs/simple_item_selector.cpp
gui/dialogs/sp_options_configure.cpp
gui/dialogs/statistics_dialog.cpp
gui/dialogs/theme_list.cpp
gui/dialogs/tip.cpp
gui/dialogs/title_screen.cpp
@ -532,7 +533,6 @@ wesnoth_sources = Split("""
scripting/plugins/manager.cpp
settings.cpp
side_filter.cpp
statistics_dialog.cpp
statistics.cpp
storyscreen/controller.cpp
storyscreen/interface.cpp

View file

@ -0,0 +1,285 @@
/*
Copyright (C) 2016 by the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/dialogs/statistics_dialog.hpp"
#include "config_assign.hpp"
#include "font/constants.hpp"
#include "formatter.hpp"
#include "gettext.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/helper.hpp"
#include "gui/widgets/label.hpp"
#ifdef GUI2_EXPERIMENTAL_LISTBOX
#include "gui/widgets/list.hpp"
#else
#include "gui/widgets/listbox.hpp"
#endif
#include "gui/widgets/menu_button.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "team.hpp"
#include "units/types.hpp"
#include "utils/functional.hpp"
#include <iostream>
namespace gui2
{
namespace dialogs
{
static bool use_campaign = false;
REGISTER_DIALOG(statistics_dialog)
statistics_dialog::statistics_dialog(const team& current_team)
: current_team_(current_team)
, campaign_(statistics::calculate_stats(current_team.save_id()))
, scenarios_(statistics::level_stats(current_team.save_id()))
, scenario_index_(scenarios_.size() - 1)
, main_stat_table_()
{
}
void statistics_dialog::pre_show(window& window)
{
//
// Set title
//
label& title = find_widget<label>(&window, "title", false);
title.set_label((formatter() << title.get_label() << " (" << current_team_.side_name() << ")").str());
//
// Set up scenario menu
//
std::vector<config> menu_items;
for(const auto& scenario : scenarios_) {
menu_items.push_back(config_of("label", *scenario.first));
}
menu_button& scenario_menu = find_widget<menu_button>(&window, "scenario_menu", false);
scenario_menu.set_values(menu_items, scenario_index_);
scenario_menu.connect_click_handler(std::bind(&statistics_dialog::on_scenario_select, this, std::ref(window)));
//
// Set up tab toggle
//
listbox& tab_bar = find_widget<listbox>(&window, "tab_bar", false);
tab_bar.select_row(use_campaign);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
connect_signal_notify_modified(*tab_bar,
std::bind(&statistics_dialog::on_tab_select, *this, std::ref(window)));
#else
tab_bar.set_callback_value_change(
dialog_callback<statistics_dialog, &statistics_dialog::on_tab_select>);
#endif
//
// Set up primary stats list
//
listbox& stat_list = find_widget<listbox>(&window, "stats_list_main", false);
#ifdef GUI2_EXPERIMENTAL_LISTBOX
connect_signal_notify_modified(*stat_list,
std::bind(&statistics_dialog::on_primary_list_select, *this, std::ref(window)));
#else
stat_list.set_callback_value_change(
dialog_callback<statistics_dialog, &statistics_dialog::on_primary_list_select>);
#endif
update_lists(window);
}
inline const statistics::stats& statistics_dialog::current_stats()
{
return use_campaign ? campaign_ : *scenarios_[scenario_index_].second;
}
void statistics_dialog::add_stat_row(window& window, const std::string& type, const statistics::stats::str_int_map& value, const bool has_cost)
{
listbox& stat_list = find_widget<listbox>(&window, "stats_list_main", false);
std::map<std::string, string_map> data;
string_map item;
item["label"] = type;
data.emplace("stat_type", item);
item["label"] = std::to_string(statistics::sum_str_int_map(value));
data.emplace("stat_detail", item);
item["label"] = has_cost ? std::to_string(statistics::sum_cost_str_int_map(value)) : font::unicode_em_dash;
data.emplace("stat_cost", item);
stat_list.add_row(data);
main_stat_table_.push_back(&value);
}
void statistics_dialog::add_damage_row(
window& window,
const std::string& type,
const long long& damage,
const long long& expected,
const long long& turn_damage,
const long long& turn_expected,
const bool show_this_turn)
{
listbox& damage_list = find_widget<listbox>(&window, "stats_list_damage", false);
std::map<std::string, string_map> data;
string_map item;
item["label"] = type;
data.emplace("damage_type", item);
const int shift = statistics::stats::decimal_shift;
const long long dsa = shift * damage - expected;
const long long dst = shift * turn_damage - turn_expected;
std::ostringstream str;
str << damage << " / "
<< (expected * 10 + shift / 2) / shift * 0.1
<< " " // TODO: should probably make this two columns
<< ((dsa < 0) ^ (expected < 0) ? "" : "+")
<< (expected == 0 ? 0 : 100 * dsa / expected) << '%';
item["label"] = str.str();
data.emplace("damage_overall", item);
str.str("");
if(show_this_turn) {
str << turn_damage << " / "
<< (turn_expected * 10 + shift / 2) / shift * 0.1
<< " " // TODO: should probably make this two columns
<< ((dst < 0) ^ (turn_expected < 0) ? "" : "+")
<< (turn_expected == 0 ? 0 : 100 * dst / turn_expected) << '%';
item["label"] = str.str();
data.emplace("damage_this_turn", item);
}
damage_list.add_row(data);
}
void statistics_dialog::update_lists(window& window)
{
//
// Update primary stats list
//
listbox& stat_list = find_widget<listbox>(&window, "stats_list_main", false);
stat_list.clear();
main_stat_table_.clear();
const statistics::stats& stats = current_stats();
add_stat_row(window, _("Recruits"), stats.recruits);
add_stat_row(window, _("Recalls"), stats.recalls);
add_stat_row(window, _("Advancements"), stats.advanced_to, false);
add_stat_row(window, _("Losses"), stats.deaths);
add_stat_row(window, _("Kills"), stats.killed);
// Update unit count list
on_primary_list_select(window);
//
// Update damage stats list
//
const bool show_this_turn = use_campaign || scenario_index_ + 1 == scenarios_.size();
listbox& damage_list = find_widget<listbox>(&window, "stats_list_damage", false);
damage_list.clear();
add_damage_row(window, _("Inflicted"),
stats.damage_inflicted,
stats.expected_damage_inflicted,
stats.turn_damage_inflicted,
stats.turn_expected_damage_inflicted,
show_this_turn
);
add_damage_row(window, _("Taken"),
stats.damage_taken,
stats.expected_damage_taken,
stats.turn_damage_taken,
stats.turn_expected_damage_taken,
show_this_turn
);
}
void statistics_dialog::on_tab_select(window& window)
{
const bool is_campaign_tab = find_widget<listbox>(&window, "tab_bar", false).get_selected_row() == 1;
if(use_campaign != is_campaign_tab) {
use_campaign = is_campaign_tab;
update_lists(window);
}
}
void statistics_dialog::on_scenario_select(window& window)
{
const size_t new_index = find_widget<menu_button>(&window, "scenario_menu", false).get_value();
if(scenario_index_ != new_index) {
scenario_index_ = new_index;
update_lists(window);
}
}
void statistics_dialog::on_primary_list_select(window& window)
{
const int selected_row = find_widget<listbox>(&window, "stats_list_main", false).get_selected_row();
if(selected_row == -1) {
return;
}
listbox& unit_list = find_widget<listbox>(&window, "stats_list_units", false);
unit_list.clear();
for(const auto& i : *main_stat_table_[selected_row]) {
const unit_type* type = unit_types.find(i.first);
if(!type) {
continue;
}
std::map<std::string, string_map> data;
string_map item;
item["label"] = (formatter() << type->image() << "~RC(" << type->flag_rgb() << ">" << current_team_.color() << ")").str();
data.emplace("unit_image", item);
item["label"] = type->type_name();
data.emplace("unit_name", item);
item["label"] = (formatter() << i.second << font::unicode_multiplication_sign).str();
data.emplace("unit_count", item);
unit_list.add_row(data);
}
}
} // namespace dialogs
} // namespace gui2

View file

@ -0,0 +1,83 @@
/*
Copyright (C) 2016 by the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef GUI_DIALOGS_STATISTICS_DIALOG_HPP_INCLUDED
#define GUI_DIALOGS_STATISTICS_DIALOG_HPP_INCLUDED
#include "gui/dialogs/dialog.hpp"
#include "statistics.hpp"
class CVideo;
class team;
namespace gui2
{
class menu_button;
namespace dialogs
{
class statistics_dialog : public modal_dialog
{
public:
statistics_dialog(const team& current_team);
static void display(const team& current_team, CVideo& video)
{
statistics_dialog(current_team).show(video);
}
private:
/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
virtual const std::string& window_id() const;
/** Inherited from modal_dialog. */
void pre_show(window& window);
/**
* Picks out the stats structure that was selected for displaying.
*/
inline const statistics::stats & current_stats();
void add_stat_row(window& window, const std::string& type, const statistics::stats::str_int_map& value, const bool has_cost = true);
void add_damage_row(
window& window,
const std::string& type,
const long long& damage,
const long long& expected,
const long long& turn_damage,
const long long& turn_expected,
const bool show_this_turn);
void update_lists(window& window);
void on_primary_list_select(window& window);
void on_scenario_select(window& window);
void on_tab_select(window& window);
const team& current_team_;
const statistics::stats campaign_;
const statistics::levels scenarios_;
size_t scenario_index_;
std::vector<const statistics::stats::str_int_map*> main_stat_table_;
};
} // namespace dialogs
} // namespace gui2
#endif /* ! GUI_DIALOGS_STATISTICS_DIALOG_HPP_INCLUDED */

View file

@ -29,6 +29,7 @@
#include "ai/manager.hpp"
#include "chat_command_handler.hpp"
#include "config_assign.hpp"
#include "construct_dialog.hpp"
#include "display_chat_manager.hpp"
#include "formatter.hpp"
#include "formula/string_utils.hpp"
@ -50,6 +51,7 @@
#include "gui/dialogs/multiplayer/mp_change_control.hpp"
#include "gui/dialogs/preferences_dialog.hpp"
#include "gui/dialogs/simple_item_selector.hpp"
#include "gui/dialogs/statistics_dialog.hpp"
#include "gui/dialogs/edit_text.hpp"
#include "gui/dialogs/game_stats.hpp"
#include "gui/dialogs/unit_create.hpp"
@ -78,7 +80,6 @@
#include "scripting/game_lua_kernel.hpp"
#include "scripting/plugins/manager.hpp"
#include "sound.hpp"
#include "statistics_dialog.hpp"
#include "synced_context.hpp"
#include "terrain/builder.hpp"
#include "units/unit.hpp"
@ -133,15 +134,7 @@ void menu_handler::objectives()
void menu_handler::show_statistics(int side_num)
{
team &current_team = teams()[side_num - 1];
// Current Player name
const std::string &player = current_team.side_name();
//add player's name to title of dialog
std::stringstream title_str;
title_str << _("Statistics") << " (" << player << ")";
statistics_dialog stats_dialog(*gui_, title_str.str(),
side_num, current_team.save_id(), player);
stats_dialog.show();
gui2::dialogs::statistics_dialog::display(teams()[side_num - 1], gui_->video());
}
void menu_handler::unit_list()

View file

@ -1,326 +0,0 @@
/*
Copyright (C) 2006 - 2016 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
wesnoth playturn Copyright (C) 2003 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "gettext.hpp"
#include "font/marked-up_text.hpp"
#include "statistics_dialog.hpp"
#include "units/types.hpp"
#include "wml_separators.hpp"
#include "game_display.hpp"
bool statistics_dialog::use_campaign_ = false;
// These values just need to be larger than the number of rows in the dialog.
static const int BUTTON_SCENE = 101;
static const int BUTTON_TOGGLE = 102;
namespace {
std::vector<std::string> create_unit_table(const statistics::stats::str_int_map& m, unsigned int team)
{
std::vector<std::string> table;
for(statistics::stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
const unit_type *type = unit_types.find(i->first);
if (!type) continue;
std::stringstream str;
str << IMAGE_PREFIX << type->image();
str << "~RC(" << type->flag_rgb() << ">" << team << ")";
str << COLUMN_SEPARATOR << type->type_name() << COLUMN_SEPARATOR << i->second << "\n";
table.push_back(str.str());
}
return table;
}
void make_damage_line(std::vector<std::string>& items, const std::string& header,
const long long& damage, const long long& expected,
const long long& turn_damage, const long long& turn_expected,
bool show_this_turn)
{
int shift = statistics::stats::decimal_shift;
long long dsa = shift * damage - expected;
long long dst = shift * turn_damage - turn_expected;
std::ostringstream str;
str << header << COLUMN_SEPARATOR
<< damage << " / "
<< (expected * 10 + shift / 2) / shift * 0.1
<< COLUMN_SEPARATOR
<< ((dsa < 0) ^ (expected < 0) ? "" : "+")
<< (expected == 0 ? 0 : 100 * dsa / expected) << '%';
if ( show_this_turn ) {
str << COLUMN_SEPARATOR
<< COLUMN_SEPARATOR
<< turn_damage << " / "
<< (turn_expected * 10 + shift / 2) / shift * 0.1
<< COLUMN_SEPARATOR
<< ((dst < 0) ^ (turn_expected < 0) ? "" : "+")
<< (turn_expected == 0 ? 0 : 100 * dst / turn_expected) << '%';
}
items.push_back(str.str());
}
} //end anonymous namespace
/**
* Picks out the stats structure that was selected for displaying.
*/
inline const statistics::stats & statistics_dialog::current_stats()
{
return use_campaign_ ? campaign_ : *scenarios_[scenario_index_].second;
}
void statistics_dialog::action(gui::dialog_process_info &dp_info)
{
int sel = get_menu().selection();
bool has_details = sel < 5 && sel >= 0 && unit_count_[sel] > 0;
detail_btn_->enable(has_details);
if(dp_info.double_clicked && has_details) {
set_result(sel);
} else if(dp_info.new_key_down && !dp_info.key_down) {
set_result(gui::CLOSE_DIALOG);
}
// Prepare the sub-dialog for Statistic Details
std::string title;
std::vector<std::string> items_sub;
switch(result()) {
case gui::CLOSE_DIALOG:
break;
case 0:
items_sub = create_unit_table(current_stats().recruits, team_num_);
title = _("Recruits");
break;
case 1:
items_sub = create_unit_table(current_stats().recalls, team_num_);
title = _("Recalls");
break;
case 2:
items_sub = create_unit_table(current_stats().advanced_to, team_num_);
title = _("Advancements");
break;
case 3:
items_sub = create_unit_table(current_stats().deaths, team_num_);
title = _("Losses");
break;
case 4:
// Give kills a (probably) different team color.
items_sub = create_unit_table(current_stats().killed, team_num_ == 1 ? 2 : 1);
title = _("Kills");
break;
case BUTTON_SCENE:
// Scenario selection.
do_scene_selection();
set_result(gui::CONTINUE_DIALOG);
break;
case BUTTON_TOGGLE:
// Toggle between campaign and scenario stats.
display_stats(!use_campaign_);
set_result(gui::CONTINUE_DIALOG);
break;
default:
break;
}
if (items_sub.empty() == false) {
gui::dialog d(get_video(), title + " (" + player_name_ + ")", "", gui::CLOSE_ONLY);
d.set_menu(items_sub);
d.show();
dp_info.clear_buttons();
set_result(gui::CONTINUE_DIALOG);
}
}
statistics_dialog::statistics_dialog(game_display &disp,
const std::string& title,
const unsigned int team,
const std::string& team_id,
const std::string& player) :
dialog(disp.video(), title, "", gui::NULL_DIALOG),
detail_btn_(new gui::standard_dialog_button(disp.video(), _("Details"), 0 , false)),
toggle_btn_(new gui::dialog_button(disp.video(), "", gui::button::TYPE_PRESS, BUTTON_TOGGLE)),
scene_btn_(new gui::dialog_button(disp.video(), _("Select Scenario"), gui::button::TYPE_PRESS, BUTTON_SCENE)),
player_name_(player),
campaign_(statistics::calculate_stats(team_id)),
scenarios_(statistics::level_stats(team_id)),
scenario_index_(scenarios_.size() - 1), // current scenario
team_num_(team),
unit_count_(5,0)
{
if ( scenarios_.size() > 1 ) {
add_button(scene_btn_, gui::dialog::BUTTON_EXTRA_LEFT);
add_button(toggle_btn_, gui::dialog::BUTTON_EXTRA_LEFT);
}
add_button(detail_btn_, gui::dialog::BUTTON_EXTRA);
add_button(new gui::standard_dialog_button(disp.video(), _("Close"), 1, true),
gui::dialog::BUTTON_STANDARD);
// Initialize the displayed data.
if ( use_campaign_ || scenarios_.size() == 1 )
display_stats(use_campaign_);
else {
// Starting with the scenario stats, but we need to make sure the
// window is wide enough for the campaign stats.
display_stats(true);
layout();
display_stats(false);
}
}
statistics_dialog::~statistics_dialog()
{
}
/**
* Fills in the text to be displayed in the dialog.
* This also updates the scenario/campaign toggle button.
*
* @param[in] campaign Indicates whether or not the campaign stats are to
* be displayed.
*/
void statistics_dialog::display_stats(bool campaign)
{
// Record which stats we will display.
use_campaign_ = campaign;
const statistics::stats & stats = current_stats();
const bool show_this_turn =
use_campaign_ || scenario_index_ + 1 == scenarios_.size();
int n, cost;
std::vector<std::string> items;
// The heading for the menu items:
{
std::stringstream str;
str << HEADING_PREFIX
<< COLUMN_SEPARATOR
<< font::BOLD_TEXT << (use_campaign_ ? _("Campaign") : _("Scenario"));
items.push_back(str.str());
}
// Prepare the menu items
{
std::stringstream str;
n = statistics::sum_str_int_map(stats.recruits);
cost = stats.recruit_cost;
unit_count_[0] = n;
str << _("Recruits") << COLUMN_SEPARATOR << n
<< COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold.png"
<< COLUMN_SEPARATOR << cost;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats.recalls);
cost = stats.recall_cost;
unit_count_[1] = n;
str << _("Recalls") << COLUMN_SEPARATOR << n
<< COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold.png"
<< COLUMN_SEPARATOR << cost;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats.advanced_to);
unit_count_[2] = n;
str << _("Advancements") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats.deaths);
unit_count_[3] = n;
cost = statistics::sum_cost_str_int_map(stats.deaths);
str << _("Losses") << COLUMN_SEPARATOR << n
<< COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold.png"
<< COLUMN_SEPARATOR << cost;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats.killed);
unit_count_[4] = n;
cost = statistics::sum_cost_str_int_map(stats.killed);
str << _("Kills") << COLUMN_SEPARATOR << n
<< COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold.png"
<< COLUMN_SEPARATOR << cost;
items.push_back(str.str());
}
items.push_back("");
{
std::stringstream str;
str << font::BOLD_TEXT << _("Damage")
<< COLUMN_SEPARATOR << _("Overall");
if ( show_this_turn ) {
str << COLUMN_SEPARATOR
<< COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << _("This Turn");
}
items.push_back(str.str());
}
make_damage_line(items, _("Inflicted"),
stats.damage_inflicted, stats.expected_damage_inflicted,
stats.turn_damage_inflicted, stats.turn_expected_damage_inflicted,
show_this_turn);
make_damage_line(items, _("Taken"),
stats.damage_taken, stats.expected_damage_taken,
stats.turn_damage_taken, stats.turn_expected_damage_taken,
show_this_turn);
set_menu_items(items, true);
toggle_btn_->set_label(use_campaign_ ? _("Scenario") : _("Campaign"));
scene_btn_->enable(!use_campaign_);
}
/**
* Implements the scenario selection popup.
*/
void statistics_dialog::do_scene_selection()
{
// Prepare a list of scenario names.
std::vector<std::string> names;
for ( size_t i = 0; i != scenarios_.size(); ++i )
names.push_back(*scenarios_[i].first);
// Let the player choose a scenario.
SDL_Rect const &loc = scene_btn_->location();
size_t new_scenario = gui::show_dialog(get_video(), nullptr, "", "",
gui::MESSAGE, &names, nullptr, "", nullptr,
-1, nullptr, loc.x, loc.y + loc.h);
if ( new_scenario != scenario_index_ && new_scenario < scenarios_.size() )
{
// Switch the displayed data to the selected scenario.
scenario_index_ = new_scenario;
scene_btn_->set_label(*scenarios_[new_scenario].first);
display_stats(false);
}
}

View file

@ -1,60 +0,0 @@
/*
Copyright (C) 2006 - 2016 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
wesnoth playturn Copyright (C) 2003 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef STATISTICS_DIALOG_HPP_INCLUDED
#define STATISTICS_DIALOG_HPP_INCLUDED
#include "construct_dialog.hpp"
#include "statistics.hpp"
#include <vector>
#include <string>
class game_display;
class statistics_dialog : public gui::dialog
{
public:
statistics_dialog(game_display &disp,
const std::string& title,
const unsigned int team,
const std::string& team_id,
const std::string& player);
~statistics_dialog();
protected:
void action(gui::dialog_process_info &dp_info);
private:
/// Picks out the stats structure that was selected for displaying.
inline const statistics::stats & current_stats();
/// Fills in the text to be displayed in the dialog.
void display_stats(bool campaign);
/// Implements the scenario selection popup.
void do_scene_selection();
gui::dialog_button *detail_btn_;
gui::dialog_button *toggle_btn_;
gui::dialog_button *scene_btn_;
std::string player_name_;
const statistics::stats campaign_;
const statistics::levels scenarios_;
size_t scenario_index_;
unsigned int team_num_;
std::vector<int> unit_count_;
// This is static so the setting can be remembered throughout the session.
static bool use_campaign_;
};
#endif

View file

@ -86,6 +86,7 @@
#include "gui/dialogs/screenshot_notification.hpp"
#include "gui/dialogs/select_orb_colors.hpp"
#include "gui/dialogs/sp_options_configure.hpp"
#include "gui/dialogs/statistics_dialog.hpp"
#include "gui/dialogs/theme_list.hpp"
#include "gui/dialogs/title_screen.hpp"
#include "gui/dialogs/tip.hpp"
@ -438,6 +439,7 @@ BOOST_AUTO_TEST_CASE(test_gui2)
test<screenshot_notification>();
test<select_orb_colors>();
test<sp_options_configure>();
test<statistics_dialog>();
test<theme_list>();
//test<title_screen>();
test<transient_message>();
@ -1153,5 +1155,16 @@ struct dialog_tester<sp_options_configure>
}
};
template<>
struct dialog_tester<statistics_dialog>
{
team t;
dialog_tester() : t() {}
statistics_dialog* create()
{
return new statistics_dialog(t);
}
};
} // namespace