Bring back MP options (patch by lipkab).

This commit is contained in:
Andrius Silinskas 2013-08-30 15:46:50 +01:00
parent 311d101fe5
commit c84e94fe9b
8 changed files with 1029 additions and 15 deletions

View file

@ -18946,6 +18946,14 @@
RelativePath="..\..\src\mp_game_utils.hpp"
>
</File>
<File
RelativePath="..\..\src\mp_options.cpp"
>
</File>
<File
RelativePath="..\..\src\mp_options.hpp"
>
</File>
<File
RelativePath="..\..\src\multiplayer.cpp"
>

View file

@ -769,6 +769,7 @@ set(wesnoth-main_SRC
mp_depcheck.cpp
mp_game_settings.cpp
mp_game_utils.cpp
mp_options.cpp
multiplayer.cpp
multiplayer_configure.cpp
multiplayer_connect.cpp

View file

@ -437,6 +437,7 @@ wesnoth_sources = Split("""
mp_depcheck.cpp
mp_game_settings.cpp
mp_game_utils.cpp
mp_options.cpp
multiplayer.cpp
multiplayer_configure.cpp
multiplayer_connect.cpp

View file

@ -20,6 +20,7 @@
#include "game_config_manager.hpp"
#include "gettext.hpp"
#include "log.hpp"
#include "mp_options.hpp"
#include "replay.hpp"
#include "savegame.hpp"
#include "tod_manager.hpp"
@ -81,10 +82,8 @@ config initial_level_config(game_display& disp, const mp_game_settings& params,
level.add_child("multiplayer", params.to_config());
// Convert options to events
//FIXME
//level.add_child_at("event", mp::options::to_event(
// params.options.find_child("multiplayer", "id",
// params.mp_scenario)), 0);
level.add_child_at("event", options::to_event(params.options.find_child(
"multiplayer", "id", params.mp_scenario)), 0);
level["next_underlying_unit_id"] = 0;
n_unit::id_manager::instance().clear();
@ -126,31 +125,27 @@ config initial_level_config(game_display& disp, const mp_game_settings& params,
}
else
{
/*config& cfg =*/
level.add_child("era", era_cfg);
config& cfg = level.add_child("era", era_cfg);
const config& custom_side = resources::config_manager->
game_config().find_child("multiplayer_side", "id", "Custom");
level.child("era").add_child_at("multiplayer_side", custom_side, 0);
// Convert options to event
//FIXME
//cfg.add_child_at("event", mp::options::to_event(
// params.options.find_child("era", "id", era)), 0);
cfg.add_child_at("event", options::to_event(
params.options.find_child("era", "id", era)), 0);
}
// Add modifications
const std::vector<std::string>& mods = params.active_mods;
for (unsigned i = 0; i < mods.size(); i++) {
/*config& cfg = */
level.add_child("modification",
config& cfg = level.add_child("modification",
resources::config_manager->
game_config().find_child("modification", "id", mods[i]));
// Convert options to event
//FIXME
//cfg.add_child_at("event", mp::options::to_event(
// params.options.find_child("modification", "id", mods[i])), 0);
cfg.add_child_at("event", options::to_event(
params.options.find_child("modification", "id", mods[i])), 0);
}
// This will force connecting clients to be using the same version number as us.

602
src/mp_options.cpp Normal file
View file

@ -0,0 +1,602 @@
/*
Copyright (C) 2012 - 2013 by Boldizsár Lipka <lipkab@zoho.com>
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 "mp_options.hpp"
#include "gettext.hpp"
#include "gui/auxiliary/find_widget.tpp"
#include "gui/auxiliary/window_builder.hpp"
#include "gui/dialogs/transient_message.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/slider.hpp"
#include "gui/widgets/text_box.hpp"
#include "gui/widgets/toggle_button.hpp"
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
static lg::log_domain log_mp_create_options("mp/create/options");
#define DBG_MP LOG_STREAM(debug, log_mp_create_options)
namespace
{
// helper function
config& add_column(config& parent, const std::string& halign = "left",
float grow_factor = 0)
{
config& result = parent.add_child("column");
result["horizontal_alignment"] = halign;
result["grow_factor"] = grow_factor;
result["border"] = "all";
result["border_size"] = 5;
return result;
}
}
namespace mp
{
namespace options
{
config to_event(const config& cfg)
{
config result;
if (!cfg) {
return result;
}
result["name"] = "prestart";
BOOST_FOREACH (const config& c, cfg.child_range("option")) {
config ev;
ev["name"] = c["id"];
ev["value"] = c["value"];
result.add_child("set_variable", ev);
}
return result;
}
void manager::init_info(const config& cfg, const std::string& key)
{
BOOST_FOREACH (const config& comp, cfg.child_range(key)) {
config entry;
entry["id"] = comp["id"];
entry["name"] = comp["name"];
if (comp.has_child("options") && comp["allow_new_game"].to_bool(true)) {
const config& options = comp.child("options");
BOOST_FOREACH (const config::any_child& c,
options.all_children_range()) {
entry.add_child(c.key, c.cfg);
}
}
// We need to store components even if they don't have any options in
// order to have set_xxx_by_index work properly
options_info_.add_child(key, entry);
}
}
manager::manager(const config& gamecfg, CVideo& video, const config& values)
: options_info_()
, values_(values)
, video_(video)
, era_()
, scenario_()
, modifications_()
{
DBG_MP << "Initializing the options manager" << std::endl;
init_info(gamecfg, "modification");
init_info(gamecfg, "era");
init_info(gamecfg, "multiplayer");
BOOST_FOREACH (const config::any_child& i,
options_info_.all_children_range())
{
BOOST_FOREACH (const config::any_child& j, i.cfg.all_children_range())
{
if (is_valid_option(j.key, j.cfg)) {
config& value = get_value_cfg(j.cfg["id"]);
value["value"] = get_stored_value(j.cfg["id"]);
}
}
}
}
void manager::set_values(const config& c)
{
values_ = c;
}
void manager::set_era(const std::string& era)
{
era_ = era;
}
void manager::set_era_by_index(int index)
{
era_ = options_info_.child("era", index)["id"].str();
}
void manager::set_scenario(const std::string& scenario)
{
scenario_ = scenario;
}
void manager::set_scenario_by_index(int index)
{
scenario_ = options_info_.child("multiplayer", index - 1)["id"].str();
}
void manager::set_modifications(const std::vector<std::string>& modifications)
{
modifications_ = modifications;
}
void manager::insert_element(elem_type type, const config& data, int pos)
{
switch (type)
{
case SCENARIO:
options_info_.add_child_at("multiplayer", data, pos);
break;
case ERA:
options_info_.add_child_at("era", data, pos);
break;
case MODIFICATION:
options_info_.add_child_at("modification", data, pos);
break;
}
}
void manager::show_dialog()
{
DBG_MP << "Building the options dialog" << std::endl;
// Constructing the dialog
config dialog_cfg;
dialog_cfg.add_child("resolution");
dialog_cfg["definition"] = "default";
dialog_cfg["automatic_placement"] = true;
dialog_cfg["vertical_placement"] = "center";
dialog_cfg["horizontal_placement"] = "center";
dialog_cfg.add_child("helptip")["id"] = "tooltip_large";
dialog_cfg.add_child("tooltip")["id"] = "tooltip_large";
config& grid = dialog_cfg.add_child("grid");
// Adding widgets for available options
add_widgets(options_info_.find_child("era", "id", era_), grid);
add_widgets(options_info_.find_child("multiplayer", "id", scenario_), grid);
for (unsigned i = 0; i<modifications_.size(); i++) {
add_widgets(
options_info_.find_child("modification", "id", modifications_[i]),
grid);
}
if (grid.ordered_begin() == grid.ordered_end()) {
// No widgets were actually added, we've got nothing to show
gui2::show_transient_message(video_, "", _(
"None of the selected modifications, era or scenario provide " \
"configuration options."));
return;
}
// Dialog buttons
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& column = add_column(row, "", 1);
column["horizontal_grow"] = true;
config& widget_grid = column.add_child("grid");
config& widget_row = widget_grid.add_child("row");
widget_row["grow_factor"] = 0;
config& defaults_column = add_column(widget_row, "left", 1);
config& ok_column = add_column(widget_row, "right");
config& cancel_column = add_column(widget_row);
config& defaults_button = defaults_column.add_child("button");
defaults_button["definition"] = "default";
defaults_button["label"] = _("Defaults");
defaults_button["id"] = "restore_defaults";
config& ok_button = ok_column.add_child("button");
ok_button["definition"] = "default";
ok_button["label"] = _("OK");
ok_button["id"] = "ok";
config& cancel_button = cancel_column.add_child("button");
cancel_button["definition"] = "default";
cancel_button["label"] = _("Cancel");
cancel_button["id"] = "cancel";
// Building the window
gui2::twindow_builder::tresolution resolution(dialog_cfg);
gui2::twindow* window = gui2::build(video_, &resolution);
__tmp_set_checkbox_defaults(window);
gui2::tbutton* button = gui2::find_widget<gui2::tbutton>
(window, "restore_defaults", false, true);
// Callbacks (well, one callback)
button->connect_click_handler(boost::bind(restore_defaults, this, window));
// Show window
DBG_MP << "Showing the dialog" << std::endl;
if (window->show() == gui2::twindow::CANCEL) {
DBG_MP << "User cancelled changes" << std::endl;
delete window;
return;
}
// Saving the results
DBG_MP << "User accepted changes, saving values" << std::endl;
extract_values("era", era_, window);
extract_values("multiplayer", scenario_, window);
for (unsigned i = 0; i<modifications_.size(); i++) {
extract_values("modification", modifications_[i], window);
}
delete window;
}
void manager::add_widgets(const config& data, config& grid) const
{
if (!data.has_child("entry") &&
!data.has_child("slider") &&
!data.has_child("checkbox"))
{
//Don't display the title if there're no options at all
return;
}
{
// The title for this section
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& column = add_column(row, "left", 1);
config& caption = column.add_child("label");
caption["definition"] = "title";
caption["label"] = data["name"];
}
// Adding the widgets
BOOST_FOREACH (const config::any_child& c, data.all_children_range()) {
if (!is_valid_option(c.key, c.cfg))
{
continue;
}
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& column = add_column(row, "left", 1);
if (c.key == "entry") {
add_entry(c.cfg, column);
} else if (c.key == "slider") {
add_slider(c.cfg, column);
} else if (c.key == "checkbox") {
add_checkbox(c.cfg, column);
}
}
}
void manager::add_entry(const config& data, config& column) const
{
config& grid = column.add_child("grid");
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& label_column = add_column(row);
config& entry_column = add_column(row);
config& label = label_column.add_child("label");
label["definition"] = "default";
label["label"] = data["name"];
config& entry = entry_column.add_child("text_box");
entry["id"] = data["id"];
entry["definition"] = "default";
entry["label"] = get_stored_value(data["id"]);
entry["tooltip"] = data["description"];
}
void manager::add_slider(const config& data, config& column) const
{
config& grid = column.add_child("grid");
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& label_column = add_column(row);
config& slider_column = add_column(row);
config& label = label_column.add_child("label");
label["definition"] = "default";
label["label"] = data["name"];
config& slider = slider_column.add_child("slider");
slider["id"] = data["id"];
slider["definition"] = "default";
slider["minimum_value"] = data["min"];
slider["maximum_value"] = data["max"];
slider["step_size"] = data["step"].to_int() ? data["step"].to_int() : 1;
slider["value"] = get_stored_value(data["id"]);
slider["tooltip"] = data["description"];
}
void manager::add_checkbox(const config& data, config& column) const
{
config& grid = column.add_child("grid");
config& row = grid.add_child("row");
row["grow_factor"] = 0;
config& box_column = add_column(row);
config& checkbox = box_column.add_child("toggle_button");
checkbox["id"] = data["id"];
checkbox["definition"] = "default";
checkbox["label"] = data["name"];
checkbox["tooltip"] = data["description"];
}
config& manager::get_value_cfg(const std::string& id)
{
{
const config& value_cfg = get_value_cfg_or_empty(id);
if (!value_cfg.empty()) {
return const_cast<config&>(value_cfg);
}
}
config::any_child info = get_option_parent(id);
config* parent_cfg;
if (!values_.find_child(info.key, "id", info.cfg["id"])) {
parent_cfg = &values_.add_child(info.key);
(*parent_cfg)["id"] = info.cfg["id"];
} else {
parent_cfg = &values_.find_child(info.key, "id", info.cfg["id"]);
}
config& value_cfg = parent_cfg->add_child("option");
value_cfg["id"] = id;
return value_cfg;
}
const config& manager::get_value_cfg_or_empty(const std::string& id) const
{
static const config empty;
BOOST_FOREACH (const config::any_child& i, values_.all_children_range()) {
BOOST_FOREACH (const config& j, i.cfg.child_range("option")) {
if (j["id"] == id) {
return j;
}
}
}
return empty;
}
config::any_child manager::get_option_parent(const std::string& id) const
{
static const config empty;
static const std::string empty_key = "";
static config::any_child not_found(&empty_key, &empty);
BOOST_FOREACH (const config::any_child& i,
options_info_.all_children_range()) {
BOOST_FOREACH (const config::any_child& j, i.cfg.all_children_range()) {
if (j.cfg["id"] == id) {
return i;
}
}
}
return not_found;
}
const config& manager::get_option_info_cfg(const std::string& id) const
{
static const config empty;
BOOST_FOREACH (const config::any_child& i,
options_info_.all_children_range()) {
BOOST_FOREACH (const config::any_child& j, i.cfg.all_children_range()) {
if (j.cfg["id"] == id) {
return j.cfg;
}
}
}
return empty;
}
config::attribute_value manager::get_stored_value(const std::string& id) const
{
const config& valcfg = get_value_cfg_or_empty(id);
if (!valcfg["value"].empty()) {
// There's a saved value for this option
return valcfg["value"];
}
// Fall back to the option's default
return get_default_value(id);
}
config::attribute_value manager::get_default_value(const std::string& id) const
{
const config& optinfo = get_option_info_cfg(id);
return optinfo["default"];
}
int manager::get_slider_value(const std::string& id, gui2::twindow* win) const
{
gui2::tslider* widget =
gui2::find_widget<gui2::tslider>(win, id, false, true);
return widget->get_value();
}
bool manager::get_checkbox_value
(const std::string& id, gui2::twindow* win) const
{
gui2::ttoggle_button* widget =
gui2::find_widget<gui2::ttoggle_button>(win, id, false, true);
return widget->get_value();
}
std::string manager::get_entry_value(const std::string& id,
gui2::twindow* window) const
{
gui2::ttext_box* widget =
gui2::find_widget<gui2::ttext_box>(window, id, false, true);
return widget->text();
}
void manager::set_slider_value(int val, const std::string& id,
gui2::twindow* win) const
{
gui2::tslider* widget =
gui2::find_widget<gui2::tslider>(win, id, false, true);
widget->set_value(val);
}
void manager::set_checkbox_value(bool val, const std::string& id,
gui2::twindow* win) const
{
gui2::ttoggle_button* widget =
gui2::find_widget<gui2::ttoggle_button>(win, id, false, true);
widget->set_value(val);
}
void manager::set_entry_value(const std::string& val, const std::string& id,
gui2::twindow* win) const
{
gui2::ttext_box* widget =
gui2::find_widget<gui2::ttext_box>(win, id, false, true);
widget->set_value(val);
}
void manager::extract_values(const std::string& key, const std::string& id,
gui2::twindow* window)
{
BOOST_FOREACH (const config::any_child& c,
options_info_.find_child(key, "id", id).all_children_range())
{
if (!is_valid_option(c.key, c.cfg)) {
continue;
}
config& out = get_value_cfg(c.cfg["id"].str());
if (c.key == "entry") {
out["value"] = get_entry_value(c.cfg["id"], window);
} else if (c.key == "slider") {
out["value"] = get_slider_value(c.cfg["id"], window);
} else if (c.key == "checkbox") {
out["value"] = get_checkbox_value(c.cfg["id"], window);
}
}
}
bool manager::is_valid_option(const std::string& key, const config& option)
{
return (key == "slider" || key == "entry" || key == "checkbox") &&
(!option["id"].empty());
}
void manager::restore_defaults(manager* m, gui2::twindow* w)
{
const config& era = m->options_info_.find_child("era", "id", m->era_);
restore_defaults_for_component(era, m, w);
const config& scen = m->options_info_.find_child("multiplayer", "id",
m->scenario_);
restore_defaults_for_component(scen, m, w);
BOOST_FOREACH (const std::string& id, m->modifications_) {
const config& mod = m->options_info_.find_child("modification", "id",
id);
restore_defaults_for_component(mod, m, w);
}
}
void manager::restore_defaults_for_component(const config& c, manager* m,
gui2::twindow* w)
{
BOOST_FOREACH (const config::any_child& i, c.all_children_range()) {
if (!is_valid_option(i.key, i.cfg)) {
continue;
}
const std::string id = i.cfg["id"].str();
if (i.key == "entry") {
m->set_entry_value(m->get_default_value(id).str(), id, w);
} else if (i.key == "checkbox") {
m->set_checkbox_value(m->get_default_value(id).to_bool(), id, w);
} else if (i.key == "slider") {
m->set_slider_value(m->get_default_value(id).to_int(), id, w);
}
}
}
void manager::__tmp_set_checkbox_defaults(gui2::twindow* window) const
{
BOOST_FOREACH (const config::any_child& i,
options_info_.all_children_range())
{
BOOST_FOREACH (const config& j, i.cfg.child_range("checkbox"))
{
if (!is_valid_option("checkbox", j)) {
continue;
}
gui2::ttoggle_button* button;
button = gui2::find_widget<gui2::ttoggle_button>
(window, j["id"].str(), false, false);
if (button) {
button->set_value(get_stored_value(j["id"]).to_bool());
}
}
}
}
} // namespace options
} // namespace mp

390
src/mp_options.hpp Normal file
View file

@ -0,0 +1,390 @@
/*
Copyright (C) 2012 - 2013 by Boldizsár Lipka <lipkab@zoho.com>
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 MP_OPTIONS_HPP_INCLUDED
#define MP_OPTIONS_HPP_INCLUDED
#include <string>
#include "config.hpp"
#include "video.hpp"
#include "gui/widgets/widget.hpp"
#include "gui/widgets/window.hpp"
namespace mp
{
namespace options
{
config to_event(const config& options);
// TODO: there's an identical enum in mp_depcheck.hpp, maybe we should factor
// out?
enum elem_type
{
SCENARIO,
ERA,
MODIFICATION
};
class manager
{
public:
/**
* Constructor.
*
* @param gamecfg The config object holding all eras, scenarios
* and modifications.
*
* @param video The screen to display the dialog on.
*
* @param initial_values The initial values for each option.
*/
manager(const config& gamecfg, CVideo& video, const config& initial_values);
/**
* Set the current values the options. This overrides ALL previously set
* values, even if a not all options are provided a new value for.
*
* @param values The new values for each option.
*/
void set_values(const config& values);
/**
* Sets the selected era. Whenever show_dialog is called, only
* options for the selected era will be displayed.
*
* @param id The era's id.
*/
void set_era(const std::string& id);
/**
* Sets the selected era. Whenever show_dialog is called, only
* options for the selected era will be displayed.
*
* @param index The era's index.
*/
void set_era_by_index(int index);
/**
* Sets the selected scenario. Whenever show_dialog is called, only
* options for the selected scenario will be displayed.
*
* @param id The scenario's id.
*/
void set_scenario(const std::string& id);
/**
* Sets the selected scenario. Whenever show_dialog is called, only
* options for the selected scenario will be displayed.
*
* @param index The scenario's index.
*/
void set_scenario_by_index(int index);
/**
* Sets the activated modifications. Whenever show_dialog is called, only
* options for the activated modifications will be displayed.
*
* @param ids The ids of the modifications
*/
void set_modifications(const std::vector<std::string>& ids);
/**
* Add options information of an era/scenario/modification not yet in the
* database.
*
* @param type The type of the element,
*
* @param data The config object which holds the
* information about the element's options in
* an [options] child.
*
* @param pos The position to insert the element into.
*/
void insert_element(elem_type type, const config& data, int pos);
/**
* Shows the options dialog and saves the selected values.
*/
void show_dialog();
/**
* Returns the the values for each option.
*
* @return A config containing the values.
*/
const config& get_values() const { return values_; }
private:
/** Stores needed info about each element and their configuration options */
config options_info_;
/** Stores the selected values for each option */
config values_;
/** The screen to display the dialog on */
CVideo &video_;
/** The id of the selected era */
std::string era_;
/** The id of the selected scenario */
std::string scenario_;
/** The ids of the selected modifications */
std::vector<std::string> modifications_;
/**
* Adds the necessary information about the specified component
* to options_info_.
*
* @param cfg The component's data.
* @param key The component's type.
*/
void init_info(const config& cfg, const std::string& key);
/**
* Creates a widget layout based on an [options] section.
*
* @param data The [options] section.
* @param grid The grid to create the layout in.
*/
void add_widgets(const config& data, config& grid) const;
/**
* Creates a slider widget.
*
* @param data A [slider] config.
* @param column The grid cell to add the widget into.
*/
void add_slider(const config& data, config& column) const;
/**
* Creates a checkbox (toggle button) widget.
*
* @param data A [checkbox] config.
* @param column The grid cell to add the widget into.
*/
void add_checkbox(const config& data, config& column) const;
/**
* @todo Implement this function (along with a combo box widget, preferably)
*
* Creates a combo box widget.
*
* @param data A [combobox] config.
* @param column The grid cell to add the widget into.
*/
void add_combobox(const config& data, config& column) const;
/**
* Creates a text entry widget.
*
* @param data An [entry] config.
* @param column The grid cell to add the widget into.
*/
void add_entry(const config& data, config& column) const;
/**
* Returns the node which holds the selected value of an option. If that
* node is not yet created, the function creates it.
*
* @param id The id of the option.
*
* @return A reference to the config which the value
* for this option should be written into.
*/
config& get_value_cfg(const std::string& id);
/**
* Returns the node which holds the selected value of an option. If that
* node is not yet created, the function returns an empty config.
*
* @param id The id of the option.
*
* @return A reference to the config which the value
* for this option should be written into or
* an empty config if that doesn't exist.
*/
const config& get_value_cfg_or_empty(const std::string& id) const;
/**
* Returns the information about an option.
*
* @param id The id of the option.
*
* @return The config object which contains the
* settings of the option, or an empty config
* if the option was not found.
*/
const config& get_option_info_cfg(const std::string& id) const;
/**
* Finds the parent node of an options.
*
* @param id The id of the option.
*
* @return A config::any_child object containing the
* key and the data of the parent node, or ""
* for the key and an empty config if the
* option was not found.
*/
config::any_child get_option_parent(const std::string& id) const;
/**
* Retrieves the saved value for a certain option, or the default, if
* there's no such.
*
* @param id The id of the option.
*
* @return The value saved in values_ for this option
* or its specified default value if a saved
* value can't be found.
*/
config::attribute_value get_stored_value(const std::string& id) const;
/**
* Retrieves the default value for a certain option.
*
* @param id The id of the option.
*
* @return The default value for this option.
*/
config::attribute_value get_default_value(const std::string& id) const;
/**
* Gets the current value of a slider widget.
*
* @param id The id of the widget.
* @param win The window to find the widget in.
*
* @return The integer currently set on the slider.
*/
int get_slider_value(const std::string& id, gui2::twindow* win) const;
/**
* Gets the current value of a checkbox widget.
*
* @param id The id of the widget.
* @param win The window to find the widget in.
*
* @return True if the box is checked, false if not.
*/
bool get_checkbox_value(const std::string& id, gui2::twindow* win) const;
/**
* Gets the current value of a text_box widget.
*
* @param id The id of the widget.
* @param win The window to find the widget in.
*
* @return The text written in the widget.
*/
std::string get_entry_value(const std::string& id,
gui2::twindow* win) const;
/**
* Sets the value of a checkbox widget.
*
* @param val The new value.
* @param id The id of the widget.
* @param win The window which the widget is a child of.
*/
void set_slider_value(int val, const std::string& id,
gui2::twindow* win) const;
/**
* Sets the value of a slider widget.
*
* @param val The new value.
* @param id The id of the widget.
* @param win The window which the widget is a child of.
*/
void set_checkbox_value(bool val, const std::string& id,
gui2::twindow* win) const;
/**
* Sets the value of a text_box widget.
*
* @param val The new value.
* @param id The id of the widget.
* @param win The window which the widget is a child of.
*/
void set_entry_value(const std::string& val, const std::string& id,
gui2::twindow* win) const;
/**
* Writes all the values for the options of a certain component from a
* specified window into values_.
*
* @param key The component's type.
* @param id The component's id.
* @param window The window.
*/
void extract_values(const std::string& key, const std::string& id,
gui2::twindow* window);
/**
* Decides whether a config is a sane option node or not.
* A valid option node:
* - Must have an id field.
* - Its key must be "slider", "entry" or "checkbox"
*
* @param key The option's key.
* @param option The option's data.
*
* @return True if the option is valid, false if not.
*/
static bool is_valid_option(const std::string& key, const config& option);
/**
* Restores every widget's value to its default for a window.
*
* @param m A pointer to the manager which generated
* the window.
* @param w A pointer to the window itself.
*/
static void restore_defaults(manager* m, gui2::twindow* w);
/**
* Finds the widgets representing the options of a certain component in a
* window (era, scenario or modification) and sets their value to their
* defaults.
*
* @param comp The config of the component.
* @param m A pointer to the manager which generated
* the window.
* @param w A pointer to the window.
*/
static void restore_defaults_for_component(const config& comp, manager* m,
gui2::twindow* w);
/**
* @todo Implement a way to initialize the checkbox via WML and then
* remove this function altogether.
*
* Sets the default states for all checkbox widgets inside a window. All
* required data is fetched from values_ and options_info_.
*
* @param window The window.
*/
void __tmp_set_checkbox_defaults(gui2::twindow* window) const;
};
} // namespace options
} // namespace mp
#endif

View file

@ -95,7 +95,8 @@ configure::configure(game_display& disp, const config &cfg, chat& c, config& gam
entry_points_(),
show_entry_points_(false),
force_use_map_settings_check_(true),
parameters_(params)
parameters_(params),
options_manager_(cfg, disp.video(), preferences::options())
{
// Build the list of scenarios to play
@ -205,6 +206,10 @@ configure::configure(game_display& disp, const config &cfg, chat& c, config& gam
show_entry_points_ = true;
}
options_manager_.set_era(parameters_.mp_era);
options_manager_.set_scenario(parameters_.mp_scenario);
options_manager_.set_modifications(parameters_.active_mods);
utils::string_map i18n_symbols;
i18n_symbols["login"] = preferences::login();
name_entry_.set_text(vgettext("$login|s game", i18n_symbols));
@ -286,6 +291,8 @@ const mp_game_settings& configure::get_parameters()
parameters_.share_view = vision_combo_.selected() == 0;
parameters_.share_maps = vision_combo_.selected() == 1;
parameters_.options = options_manager_.get_values();
return parameters_;
}
@ -316,6 +323,10 @@ void configure::process_event()
, disp_.video());
}
if(options_.pressed()) {
options_manager_.show_dialog();
}
if (entry_points_combo_.changed()) {
const config& scenario = *entry_points_[entry_points_combo_.selected()];
parameters_.scenario_data = scenario;
@ -577,6 +588,9 @@ void configure::layout_children(const SDL_Rect& rect)
countdown_action_bonus_slider_.set_location(xpos, ypos);
ypos += countdown_action_bonus_slider_.height() + border_size;
options_.set_location(xpos, ypos);
ypos += options_.height() + border_size;
if (show_entry_points_) {
ypos += border_size;
entry_points_label_.set_location(xpos, ypos);

View file

@ -23,6 +23,7 @@
#include "widgets/combo.hpp"
#include "generators/mapgen.hpp"
#include "tooltips.hpp"
#include "mp_options.hpp"
namespace mp {
@ -92,6 +93,8 @@ private:
bool force_use_map_settings_check_;
mp_game_settings parameters_;
options::manager options_manager_;
};
} // end namespace mp