Add a new give_control command.
Applies patch #2625 with some minor modifications.
This commit is contained in:
parent
0f67c8db6a
commit
4ac8cababc
10 changed files with 703 additions and 11 deletions
|
@ -6,6 +6,9 @@ Version 1.9.5+svn:
|
||||||
* Language and i18n:
|
* Language and i18n:
|
||||||
* Updated translations: British English, French, Galician, German, Greek,
|
* Updated translations: British English, French, Galician, German, Greek,
|
||||||
Irish, Japanese, Old English, Spanish
|
Irish, Japanese, Old English, Spanish
|
||||||
|
* User interface:
|
||||||
|
* Patch #2625: added a GUI interface to changing control in multiplayer games. The
|
||||||
|
command to access it is currently :control_dialog
|
||||||
* WML engine:
|
* WML engine:
|
||||||
* Patch #2610: changed default for turns in [scenario] tag to -1 (unlimited)
|
* Patch #2610: changed default for turns in [scenario] tag to -1 (unlimited)
|
||||||
* Introduced [recall]check_passability=yes|no key (default yes)
|
* Introduced [recall]check_passability=yes|no key (default yes)
|
||||||
|
|
216
data/gui/default/window/mp_change_control.cfg
Normal file
216
data/gui/default/window/mp_change_control.cfg
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#textdomain wesnoth-lib
|
||||||
|
###
|
||||||
|
### Definition of the control panel window.
|
||||||
|
###
|
||||||
|
|
||||||
|
#define _GUI_SIDES_LISTBOX
|
||||||
|
[listbox]
|
||||||
|
id = "sides_list"
|
||||||
|
definition = "default"
|
||||||
|
[header]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
grow_factor = 1
|
||||||
|
horizontal_grow = "true"
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
|
||||||
|
[label]
|
||||||
|
id = "side_title"
|
||||||
|
definition = "default"
|
||||||
|
label = _ "Side"
|
||||||
|
[/label]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/header]
|
||||||
|
|
||||||
|
[list_definition]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
vertical_grow = "true"
|
||||||
|
horizontal_grow = "true"
|
||||||
|
|
||||||
|
[toggle_panel]
|
||||||
|
definition = "default"
|
||||||
|
[grid]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
grow_factor = 1
|
||||||
|
horizontal_grow = "true"
|
||||||
|
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
|
||||||
|
[label]
|
||||||
|
id = "side"
|
||||||
|
definition = "default"
|
||||||
|
[/label]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/grid]
|
||||||
|
[/toggle_panel]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/list_definition]
|
||||||
|
[/listbox]
|
||||||
|
#enddef
|
||||||
|
|
||||||
|
#define _GUI_NICKS_LISTBOX
|
||||||
|
[listbox]
|
||||||
|
id = "nicks_list"
|
||||||
|
definition = "default"
|
||||||
|
[header]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
grow_factor = 1
|
||||||
|
horizontal_grow = "true"
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
|
||||||
|
[label]
|
||||||
|
id = "nick_title"
|
||||||
|
definition = "default"
|
||||||
|
label = _ "Nick"
|
||||||
|
[/label]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/header]
|
||||||
|
|
||||||
|
[list_definition]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
vertical_grow = "true"
|
||||||
|
horizontal_grow = "true"
|
||||||
|
|
||||||
|
[toggle_panel]
|
||||||
|
definition = "default"
|
||||||
|
[grid]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
grow_factor = 1
|
||||||
|
horizontal_grow = "true"
|
||||||
|
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
|
||||||
|
[label]
|
||||||
|
id = "nick"
|
||||||
|
definition = "default"
|
||||||
|
[/label]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/grid]
|
||||||
|
[/toggle_panel]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/list_definition]
|
||||||
|
[/listbox]
|
||||||
|
#enddef
|
||||||
|
|
||||||
|
#define _GUI_LISTBOXES_GRID
|
||||||
|
[grid]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
vertical_alignment=top
|
||||||
|
grow_factor= 0
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
{_GUI_SIDES_LISTBOX}
|
||||||
|
[/column]
|
||||||
|
[column]
|
||||||
|
vertical_alignment=top
|
||||||
|
grow factor = 1
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
{_GUI_NICKS_LISTBOX}
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/grid]
|
||||||
|
#enddef
|
||||||
|
|
||||||
|
#define _GUI_BUTTONS_GRID
|
||||||
|
[grid]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
grow_factor = 7
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
horizontal_alignment = "left"
|
||||||
|
[spacer]
|
||||||
|
definition = "default"
|
||||||
|
[/spacer]
|
||||||
|
[/column]
|
||||||
|
[column]
|
||||||
|
grow_factor = 0
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
[button]
|
||||||
|
id = "ok"
|
||||||
|
definition = "default"
|
||||||
|
label = _ "OK"
|
||||||
|
[/button]
|
||||||
|
[/column]
|
||||||
|
[column]
|
||||||
|
grow_factor = 0
|
||||||
|
border = "all"
|
||||||
|
border_size = 5
|
||||||
|
[button]
|
||||||
|
id = "cancel"
|
||||||
|
definition = "default"
|
||||||
|
label = _ "Cancel"
|
||||||
|
[/button]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/grid]
|
||||||
|
#enddef
|
||||||
|
|
||||||
|
[window]
|
||||||
|
id = "mp_change_control"
|
||||||
|
description = "Dialog used to change side's controller during MP."
|
||||||
|
|
||||||
|
[resolution]
|
||||||
|
definition = "default"
|
||||||
|
automatic_placement = "true"
|
||||||
|
vertical_placement = "center"
|
||||||
|
horizontal_placement = "center"
|
||||||
|
|
||||||
|
[tooltip]
|
||||||
|
id = "tooltip_large"
|
||||||
|
[/tooltip]
|
||||||
|
|
||||||
|
[helptip]
|
||||||
|
id = "tooltip_large"
|
||||||
|
[/helptip]
|
||||||
|
|
||||||
|
[grid]
|
||||||
|
[row] #header
|
||||||
|
grow_factor = 0
|
||||||
|
|
||||||
|
[column]
|
||||||
|
grow_factor = 7
|
||||||
|
horizontal_alignment = "left"
|
||||||
|
[label]
|
||||||
|
definition = "title"
|
||||||
|
label = _ "Change control"
|
||||||
|
[/label]
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[row]
|
||||||
|
[column]
|
||||||
|
{_GUI_LISTBOXES_GRID}
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[row] #status
|
||||||
|
grow_factor = 0
|
||||||
|
[column]
|
||||||
|
{_GUI_BUTTONS_GRID}
|
||||||
|
[/column]
|
||||||
|
[/row]
|
||||||
|
[/grid]
|
||||||
|
[/resolution]
|
||||||
|
[/window]
|
||||||
|
|
||||||
|
#undef _GUI_BUTTONS_GRID
|
||||||
|
#undef _GUI_LISTBOXES_GRID
|
||||||
|
#undef _GUI_NICKS_LISTBOX
|
||||||
|
#undef _GUI_SIDES_LISTBOX
|
|
@ -5,7 +5,10 @@ changelog: http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/changelog
|
||||||
Version 1.9.5+svn:
|
Version 1.9.5+svn:
|
||||||
* Language and i18n:
|
* Language and i18n:
|
||||||
* Updated translations: British English, French, Galician, German, Greek,
|
* Updated translations: British English, French, Galician, German, Greek,
|
||||||
Irish, Japanese, Old English, Spanish.
|
Irish, Japanese Old English.
|
||||||
|
* User interface:
|
||||||
|
* Patch #2625: added a GUI interface to changing control in multiplayer games. The
|
||||||
|
command to access it is currently :control_dialog
|
||||||
|
|
||||||
|
|
||||||
Version 1.9.5:
|
Version 1.9.5:
|
||||||
|
|
|
@ -440,6 +440,7 @@ set(wesnoth-main_SRC
|
||||||
gui/dialogs/lobby_main.cpp
|
gui/dialogs/lobby_main.cpp
|
||||||
gui/dialogs/lobby_player_info.cpp
|
gui/dialogs/lobby_player_info.cpp
|
||||||
gui/dialogs/message.cpp
|
gui/dialogs/message.cpp
|
||||||
|
gui/dialogs/mp_change_control.cpp
|
||||||
gui/dialogs/mp_cmd_wrapper.cpp
|
gui/dialogs/mp_cmd_wrapper.cpp
|
||||||
gui/dialogs/mp_connect.cpp
|
gui/dialogs/mp_connect.cpp
|
||||||
gui/dialogs/mp_create_game.cpp
|
gui/dialogs/mp_create_game.cpp
|
||||||
|
|
|
@ -307,6 +307,7 @@ wesnoth_sources = Split("""
|
||||||
gui/dialogs/lobby_player_info.cpp
|
gui/dialogs/lobby_player_info.cpp
|
||||||
gui/dialogs/message.cpp
|
gui/dialogs/message.cpp
|
||||||
gui/dialogs/mp_cmd_wrapper.cpp
|
gui/dialogs/mp_cmd_wrapper.cpp
|
||||||
|
gui/dialogs/mp_change_control.cpp
|
||||||
gui/dialogs/mp_connect.cpp
|
gui/dialogs/mp_connect.cpp
|
||||||
gui/dialogs/mp_create_game.cpp
|
gui/dialogs/mp_create_game.cpp
|
||||||
gui/dialogs/mp_create_game_set_password.cpp
|
gui/dialogs/mp_create_game_set_password.cpp
|
||||||
|
|
389
src/gui/dialogs/mp_change_control.cpp
Normal file
389
src/gui/dialogs/mp_change_control.cpp
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 by Lukasz Dobrogowski <lukasz.dobrogowski@gmail.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GETTEXT_DOMAIN "wesnoth-lib"
|
||||||
|
|
||||||
|
#include "gui/dialogs/mp_change_control.hpp"
|
||||||
|
|
||||||
|
#include "gui/dialogs/helper.hpp"
|
||||||
|
#ifdef GUI2_EXPERIMENTAL_LISTBOX
|
||||||
|
#include "gui/widgets/list.hpp"
|
||||||
|
#else
|
||||||
|
#include "gui/widgets/listbox.hpp"
|
||||||
|
#endif
|
||||||
|
#include "gui/widgets/settings.hpp"
|
||||||
|
#include "gui/widgets/window.hpp"
|
||||||
|
|
||||||
|
#include "formula_string_utils.hpp"
|
||||||
|
#include "game_display.hpp"
|
||||||
|
#include "game_preferences.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
|
#include "marked-up_text.hpp"
|
||||||
|
#include "resources.hpp"
|
||||||
|
#include "team.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <gui/widgets/button.hpp>
|
||||||
|
|
||||||
|
static lg::log_domain log_gui("gui/dialogs/mp_change_control");
|
||||||
|
#define ERR_GUI LOG_STREAM(err, log_gui)
|
||||||
|
#define WRN_GUI LOG_STREAM(warn, log_gui)
|
||||||
|
#define LOG_GUI LOG_STREAM(info, log_gui)
|
||||||
|
#define DBG_GUI LOG_STREAM(debug, log_gui)
|
||||||
|
|
||||||
|
namespace gui2 {
|
||||||
|
|
||||||
|
/*WIKI
|
||||||
|
* @page = GUIWindowDefinitionWML
|
||||||
|
* @order = 2_mp_change_control
|
||||||
|
*
|
||||||
|
* == Change control dialog ==
|
||||||
|
*
|
||||||
|
* This shows the multiplayer change control dialog.
|
||||||
|
*
|
||||||
|
* @begin{table}{dialog_widgets}
|
||||||
|
* sides_list & & listbox & m &
|
||||||
|
* List of sides participating in the MP game. $
|
||||||
|
*
|
||||||
|
* nicks_list & & listbox & m &
|
||||||
|
* List of nicks of all clients playing or observing the MP game. $
|
||||||
|
*
|
||||||
|
* @end{table}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class D, class V, void (V::*fptr)(twindow&)>
|
||||||
|
void dialog_view_callback(twidget* caller)
|
||||||
|
{
|
||||||
|
D* dialog = dynamic_cast<D*>(caller->dialog());
|
||||||
|
assert(dialog);
|
||||||
|
twindow* window = dynamic_cast<twindow*>(caller->get_window());
|
||||||
|
assert(window);
|
||||||
|
(*(dialog->get_view()).*fptr)(*window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model is an interface defining the data to be displayed or otherwise
|
||||||
|
* acted upon in the user interface.
|
||||||
|
*/
|
||||||
|
class tmp_change_control::model {
|
||||||
|
public:
|
||||||
|
model() {}
|
||||||
|
|
||||||
|
tlistbox *sides_list;
|
||||||
|
tlistbox *nicks_list;
|
||||||
|
|
||||||
|
// contains the mapping from listbox labels to actual sides
|
||||||
|
// (note that due to hidden= attribute nth list item doesn't have to be nth side)
|
||||||
|
std::vector<int> sides;
|
||||||
|
// contains the mapping from listbox labels to actual nicks
|
||||||
|
std::vector<std::string> nicks;
|
||||||
|
|
||||||
|
void clear_sides()
|
||||||
|
{
|
||||||
|
DBG_GUI << "Sides list: clearing\n";
|
||||||
|
sides_list->clear();
|
||||||
|
sides.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_side(int side_num, const std::string &label)
|
||||||
|
{
|
||||||
|
sides.push_back(side_num);
|
||||||
|
DBG_GUI << "Sides list: adding item (side_num: \"" << side_num
|
||||||
|
<< "\" label: \"" << label << "\")\n";
|
||||||
|
std::map<std::string, string_map> data;
|
||||||
|
string_map item;
|
||||||
|
item["id"] = std::string("side_")+str_cast(side_num);
|
||||||
|
item["label"] = label;
|
||||||
|
item["use_markup"] = "true";
|
||||||
|
data.insert(std::make_pair("side", item));
|
||||||
|
sides_list->add_row(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_nicks()
|
||||||
|
{
|
||||||
|
DBG_GUI << "Nicks list: clearing\n";
|
||||||
|
nicks_list->clear();
|
||||||
|
nicks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_nick(const std::string &nick, const std::string &label)
|
||||||
|
{
|
||||||
|
DBG_GUI << "Nicks list: adding item (nick: \"" << nick
|
||||||
|
<< "\" label: \"" << label << "\")\n";
|
||||||
|
nicks.push_back(nick);
|
||||||
|
std::map<std::string, string_map> data;
|
||||||
|
string_map item;
|
||||||
|
item["id"] = nick;
|
||||||
|
item["label"] = label;
|
||||||
|
item["use_markup"] = "true";
|
||||||
|
data.insert(std::make_pair("nick", item));
|
||||||
|
nicks_list->add_row(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class side_controller {
|
||||||
|
public:
|
||||||
|
side_controller(const std::string& name, tmp_change_control::model &m, int side_number)
|
||||||
|
: model_(m), name_(name), side_number_(side_number)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~side_controller()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name() const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int side_number() const
|
||||||
|
{
|
||||||
|
return side_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_nicks_list()
|
||||||
|
{
|
||||||
|
DBG_GUI << "Nicks list: showing for side " << side_number_ << '\n';
|
||||||
|
//model_.selected_side = side_number_;
|
||||||
|
model_.clear_nicks();
|
||||||
|
|
||||||
|
std::set<std::string> nicks;
|
||||||
|
for (std::vector<team>::const_iterator it = resources::teams->begin();
|
||||||
|
it != resources::teams->end(); it++)
|
||||||
|
{
|
||||||
|
if (!it->is_ai() && it->controller()!=team::team_info::EMPTY && it->current_player().size()>0)
|
||||||
|
nicks.insert(it->current_player());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<std::string> &observers = resources::screen->observers();
|
||||||
|
|
||||||
|
nicks.insert(observers.begin(),observers.end());
|
||||||
|
nicks.insert(preferences::login()); // in case we are an observer, it isn't in the observers set then
|
||||||
|
// and has to be added manually
|
||||||
|
|
||||||
|
int i = 0; // because we need to know which row contains the controlling player
|
||||||
|
|
||||||
|
foreach (const std::string &nick, nicks)
|
||||||
|
{
|
||||||
|
if (side_number_ <= static_cast<int>(resources::teams->size()) &&
|
||||||
|
resources::teams->at(side_number_-1).current_player() == nick)
|
||||||
|
{
|
||||||
|
std::string label_str = "<b>" + nick + "</b>";
|
||||||
|
model_.add_nick(nick,label_str);
|
||||||
|
model_.nicks_list->select_row(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
model_.add_nick(nick,nick);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void handle_nicks_list_selection()
|
||||||
|
{
|
||||||
|
int selected = model_.nicks_list->get_selected_row();
|
||||||
|
DBG_GUI << "Nicks list: row " << selected
|
||||||
|
<< " selected, it contains " << model_.nicks[selected] << '\n';
|
||||||
|
}
|
||||||
|
void update_view_from_model()
|
||||||
|
{
|
||||||
|
show_nicks_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tmp_change_control::model &model_;
|
||||||
|
std::string const name_;
|
||||||
|
int side_number_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The controller acts upon the model.
|
||||||
|
*
|
||||||
|
* It retrieves data from repositories, persists it, manipulates it, and
|
||||||
|
* determines how it will be displayed in the view.
|
||||||
|
*/
|
||||||
|
class tmp_change_control::controller {
|
||||||
|
public:
|
||||||
|
typedef std::vector< boost::shared_ptr<side_controller> > side_controller_ptr_vector;
|
||||||
|
controller(model &m)
|
||||||
|
: model_(m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_sides_list()
|
||||||
|
{
|
||||||
|
DBG_GUI << "Sides list: filling\n";
|
||||||
|
model_.clear_sides();
|
||||||
|
int sides = resources::teams ? static_cast<int>((*resources::teams).size()) : 0;
|
||||||
|
for( int side = 1; side<=sides; ++side)
|
||||||
|
{
|
||||||
|
if (!resources::teams->at(side-1).hidden())
|
||||||
|
{
|
||||||
|
string_map symbols;
|
||||||
|
symbols["side"] = str_cast(side);
|
||||||
|
std::string side_str = vgettext("Side $side", symbols);
|
||||||
|
side_str = font::span_color(team::get_side_color(side)) + side_str + "</span>";
|
||||||
|
model_.add_side(side,side_str);
|
||||||
|
side_controllers_.push_back(boost::shared_ptr<side_controller>(
|
||||||
|
new side_controller(side_str,model_,side)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<side_controller> get_side_controller()
|
||||||
|
{
|
||||||
|
int selected = model_.sides_list->get_selected_row();
|
||||||
|
if (selected < 0 || selected >= static_cast<int>(side_controllers_.size()))
|
||||||
|
return boost::shared_ptr<side_controller>(); // null pointer
|
||||||
|
else
|
||||||
|
return side_controllers_.at(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_sides_list_item_clicked()
|
||||||
|
{
|
||||||
|
int selected = model_.sides_list->get_selected_row();
|
||||||
|
DBG_GUI << "Sides list: selected row: " << selected
|
||||||
|
<< " for side " << model_.sides[selected] << '\n';
|
||||||
|
if (get_side_controller())
|
||||||
|
get_side_controller()->update_view_from_model();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_nicks_list_item_clicked()
|
||||||
|
{
|
||||||
|
int selected = model_.sides_list->get_selected_row();
|
||||||
|
DBG_GUI << "Nicks list: selected row: " << selected
|
||||||
|
<< " with nick " << model_.nicks[selected] << '\n';
|
||||||
|
if (get_side_controller())
|
||||||
|
get_side_controller()->handle_nicks_list_selection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_view_from_model()
|
||||||
|
{
|
||||||
|
if (get_side_controller())
|
||||||
|
get_side_controller()->update_view_from_model();
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_control(events::menu_handler *mh)
|
||||||
|
{
|
||||||
|
int selected_side = model_.sides_list->get_selected_row();
|
||||||
|
int selected_nick = model_.nicks_list->get_selected_row();
|
||||||
|
DBG_GUI << "Main: changing control of side " << model_.sides[selected_side]
|
||||||
|
<< " to nick " << model_.nicks[selected_nick] << '\n';
|
||||||
|
if (mh) // since in unit tests we pass a null pointer to it
|
||||||
|
mh->request_control_change(model_.sides[selected_side], model_.nicks[selected_nick]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
model &model_;
|
||||||
|
side_controller_ptr_vector side_controllers_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The view is an interface that displays data (the model) and routes user
|
||||||
|
* commands to the controller to act upon that data.
|
||||||
|
*/
|
||||||
|
class tmp_change_control::view {
|
||||||
|
public:
|
||||||
|
view()
|
||||||
|
: model_(),controller_(model_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void pre_show(CVideo &/*video*/, twindow &window)
|
||||||
|
{
|
||||||
|
model_.clear_sides();
|
||||||
|
controller_.show_sides_list();
|
||||||
|
model_.clear_nicks();
|
||||||
|
controller_.update_view_from_model();
|
||||||
|
window.invalidate_layout();//workaround for assertion failure
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_sides_list_item_clicked(twindow &window)
|
||||||
|
{
|
||||||
|
controller_.handle_sides_list_item_clicked();
|
||||||
|
window.invalidate_layout();//workaround for assertion failure
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_nicks_list_item_clicked(twindow &window)
|
||||||
|
{
|
||||||
|
controller_.handle_nicks_list_item_clicked();
|
||||||
|
window.invalidate_layout();//workaround for assertion failure
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(twindow &window)
|
||||||
|
{
|
||||||
|
DBG_GUI << "Main: Binding widgets and callbacks\n";
|
||||||
|
model_.sides_list = &find_widget<tlistbox>(&window, "sides_list", false);
|
||||||
|
model_.nicks_list = &find_widget<tlistbox>(&window, "nicks_list", false);
|
||||||
|
|
||||||
|
#ifdef GUI2_EXPERIMENTAL_LISTBOX
|
||||||
|
connect_signal_notify_modified(*model_.sides_list, boost::bind(
|
||||||
|
&tmp_change_control::view::handle_sides_list_item_clicked
|
||||||
|
, this
|
||||||
|
, boost::ref(window)));
|
||||||
|
|
||||||
|
connect_signal_notify_modified(*model_.nicks_list, boost::bind(
|
||||||
|
&tmp_change_control::view::handle_nicks_list_item_clicked
|
||||||
|
, this
|
||||||
|
, boost::ref(window)));
|
||||||
|
#else
|
||||||
|
model_.sides_list->set_callback_value_change(
|
||||||
|
dialog_view_callback<tmp_change_control, tmp_change_control::view, &tmp_change_control::view::handle_sides_list_item_clicked>);
|
||||||
|
|
||||||
|
model_.nicks_list->set_callback_value_change(
|
||||||
|
dialog_view_callback<tmp_change_control, tmp_change_control::view, &tmp_change_control::view::handle_nicks_list_item_clicked>);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void post_show(int retval, events::menu_handler *mh)
|
||||||
|
{
|
||||||
|
if (retval == twindow::OK)
|
||||||
|
{
|
||||||
|
controller_.change_control(mh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
model model_;
|
||||||
|
controller controller_;
|
||||||
|
};
|
||||||
|
|
||||||
|
REGISTER_DIALOG(mp_change_control)
|
||||||
|
|
||||||
|
tmp_change_control::tmp_change_control(events::menu_handler *mh)
|
||||||
|
: menu_handler_(mh), view_()
|
||||||
|
{
|
||||||
|
view_ = boost::shared_ptr<view>(new view());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<tmp_change_control::view> tmp_change_control::get_view()
|
||||||
|
{
|
||||||
|
return view_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tmp_change_control::pre_show(CVideo& video, twindow& window)
|
||||||
|
{
|
||||||
|
view_->bind(window);
|
||||||
|
view_->pre_show(video,window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tmp_change_control::post_show(twindow& /*window*/)
|
||||||
|
{
|
||||||
|
view_->post_show(get_retval(), menu_handler_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //end of namespace gui2
|
48
src/gui/dialogs/mp_change_control.hpp
Normal file
48
src/gui/dialogs/mp_change_control.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 by Lukasz Dobrogowski <lukasz.dobrogowski@gmail.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 GUI_DIALOGS_MP_CHANGE_CONTROL_HPP_INCLUDED
|
||||||
|
#define GUI_DIALOGS_MP_CHANGE_CONTROL_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include "gui/dialogs/dialog.hpp"
|
||||||
|
#include "menu_events.hpp"
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
namespace gui2 {
|
||||||
|
|
||||||
|
class tmp_change_control : public tdialog {
|
||||||
|
public:
|
||||||
|
class model;
|
||||||
|
class view;
|
||||||
|
class controller;
|
||||||
|
|
||||||
|
tmp_change_control(events::menu_handler *mh);
|
||||||
|
boost::shared_ptr<view> get_view();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Inherited from tdialog, implemented by REGISTER_DIALOG. */
|
||||||
|
virtual const std::string& window_id() const;
|
||||||
|
|
||||||
|
/** Inherited from tdialog. */
|
||||||
|
void pre_show(CVideo& video, twindow& window);
|
||||||
|
void post_show(twindow& window);
|
||||||
|
|
||||||
|
events::menu_handler *menu_handler_;
|
||||||
|
boost::shared_ptr<view> view_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! GUI_DIALOGS_MP_CHANGE_CONTROL_HPP_INCLUDED */
|
|
@ -37,6 +37,7 @@
|
||||||
#include "gui/dialogs/transient_message.hpp"
|
#include "gui/dialogs/transient_message.hpp"
|
||||||
#include "gui/dialogs/wml_message.hpp"
|
#include "gui/dialogs/wml_message.hpp"
|
||||||
#include "gui/dialogs/gamestate_inspector.hpp"
|
#include "gui/dialogs/gamestate_inspector.hpp"
|
||||||
|
#include "gui/dialogs/mp_change_control.hpp"
|
||||||
#include "gui/dialogs/data_manage.hpp"
|
#include "gui/dialogs/data_manage.hpp"
|
||||||
#include "gui/dialogs/simple_item_selector.hpp"
|
#include "gui/dialogs/simple_item_selector.hpp"
|
||||||
#include "gui/dialogs/unit_create.hpp"
|
#include "gui/dialogs/unit_create.hpp"
|
||||||
|
@ -2456,6 +2457,7 @@ class console_handler : public map_command_handler<console_handler>, private cha
|
||||||
void do_set_var();
|
void do_set_var();
|
||||||
void do_show_var();
|
void do_show_var();
|
||||||
void do_inspect();
|
void do_inspect();
|
||||||
|
void do_control_dialog();
|
||||||
void do_manage();
|
void do_manage();
|
||||||
void do_unit();
|
void do_unit();
|
||||||
// void do_buff();
|
// void do_buff();
|
||||||
|
@ -2552,6 +2554,11 @@ class console_handler : public map_command_handler<console_handler>, private cha
|
||||||
_("Grant higher privileges to Lua scripts."), "", "D");
|
_("Grant higher privileges to Lua scripts."), "", "D");
|
||||||
register_command("custom", &console_handler::do_custom,
|
register_command("custom", &console_handler::do_custom,
|
||||||
_("Set the command used by the custom command hotkey"), _("<command>[;<command>...]"));
|
_("Set the command used by the custom command hotkey"), _("<command>[;<command>...]"));
|
||||||
|
register_command("give_control"
|
||||||
|
, &console_handler::do_control_dialog
|
||||||
|
, _("Invoke a dialog allowing changing control of MP sides.")
|
||||||
|
, ""
|
||||||
|
, "N");
|
||||||
register_command("inspect", &console_handler::do_inspect,
|
register_command("inspect", &console_handler::do_inspect,
|
||||||
_("Launch the gamestate inspector"), "", "D");
|
_("Launch the gamestate inspector"), "", "D");
|
||||||
register_command("manage", &console_handler::do_manage,
|
register_command("manage", &console_handler::do_manage,
|
||||||
|
@ -3156,16 +3163,7 @@ void console_handler::do_control() {
|
||||||
command_failed(vgettext("Can't change control of out-of-bounds side: '$side'.", symbols));
|
command_failed(vgettext("Can't change control of out-of-bounds side: '$side'.", symbols));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if this is our side we are always allowed to change the controller
|
menu_handler_.request_control_change(side_num,player);
|
||||||
if (menu_handler_.teams_[side_num - 1].is_human()) {
|
|
||||||
if (player == preferences::login())
|
|
||||||
return;
|
|
||||||
menu_handler_.change_side_controller(side,player);
|
|
||||||
} else {
|
|
||||||
//it is not our side, the server will decide if we can change the
|
|
||||||
//controller (that is if we are host of the game)
|
|
||||||
menu_handler_.change_side_controller(side,player);
|
|
||||||
}
|
|
||||||
menu_handler_.textbox_info_.close(*(menu_handler_.gui_));
|
menu_handler_.textbox_info_.close(*(menu_handler_.gui_));
|
||||||
}
|
}
|
||||||
void console_handler::do_clear() {
|
void console_handler::do_clear() {
|
||||||
|
@ -3444,6 +3442,12 @@ void console_handler::do_inspect() {
|
||||||
inspect_dialog.show(resources::screen->video());
|
inspect_dialog.show(resources::screen->video());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void console_handler::do_control_dialog()
|
||||||
|
{
|
||||||
|
gui2::tmp_change_control mp_change_control(&menu_handler_);
|
||||||
|
mp_change_control.show(resources::screen->video());
|
||||||
|
}
|
||||||
|
|
||||||
void console_handler::do_manage() {
|
void console_handler::do_manage() {
|
||||||
config cfg;
|
config cfg;
|
||||||
gui2::tdata_manage manager(cfg);
|
gui2::tdata_manage manager(cfg);
|
||||||
|
@ -3607,6 +3611,21 @@ void menu_handler::user_command()
|
||||||
textbox_info_.show(gui::TEXTBOX_COMMAND,sgettext("prompt^Command:"), "", false, *gui_);
|
textbox_info_.show(gui::TEXTBOX_COMMAND,sgettext("prompt^Command:"), "", false, *gui_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menu_handler::request_control_change ( int side_num, const std::string& player )
|
||||||
|
{
|
||||||
|
std::string side = str_cast(side_num);
|
||||||
|
//if this is our side we are always allowed to change the controller
|
||||||
|
if (teams_[side_num - 1].is_human()) {
|
||||||
|
if (player == preferences::login())
|
||||||
|
return;
|
||||||
|
change_side_controller(side,player);
|
||||||
|
} else {
|
||||||
|
//it is not our side, the server will decide if we can change the
|
||||||
|
//controller (that is if we are host of the game)
|
||||||
|
change_side_controller(side,player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void menu_handler::custom_command()
|
void menu_handler::custom_command()
|
||||||
{
|
{
|
||||||
std::vector<std::string> commands = utils::split(preferences::custom_command(), ';');
|
std::vector<std::string> commands = utils::split(preferences::custom_command(), ';');
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
void unit_hold_position(mouse_handler &mousehandler, int side_num);
|
void unit_hold_position(mouse_handler &mousehandler, int side_num);
|
||||||
void end_unit_turn(mouse_handler &mousehandler, int side_num);
|
void end_unit_turn(mouse_handler &mousehandler, int side_num);
|
||||||
void search();
|
void search();
|
||||||
|
void request_control_change(int side_num, const std::string &player);
|
||||||
void user_command();
|
void user_command();
|
||||||
void custom_command();
|
void custom_command();
|
||||||
void ai_formula();
|
void ai_formula();
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "gui/dialogs/gamestate_inspector.hpp"
|
#include "gui/dialogs/gamestate_inspector.hpp"
|
||||||
#include "gui/dialogs/language_selection.hpp"
|
#include "gui/dialogs/language_selection.hpp"
|
||||||
#include "gui/dialogs/message.hpp"
|
#include "gui/dialogs/message.hpp"
|
||||||
|
#include "gui/dialogs/mp_change_control.hpp"
|
||||||
#include "gui/dialogs/mp_cmd_wrapper.hpp"
|
#include "gui/dialogs/mp_cmd_wrapper.hpp"
|
||||||
#include "gui/dialogs/mp_connect.hpp"
|
#include "gui/dialogs/mp_connect.hpp"
|
||||||
#include "gui/dialogs/mp_create_game.hpp"
|
#include "gui/dialogs/mp_create_game.hpp"
|
||||||
|
@ -371,6 +372,7 @@ BOOST_AUTO_TEST_CASE(test_gui2)
|
||||||
test<gui2::tlanguage_selection>();
|
test<gui2::tlanguage_selection>();
|
||||||
test<gui2::tmessage>();
|
test<gui2::tmessage>();
|
||||||
test<gui2::tsimple_item_selector>();
|
test<gui2::tsimple_item_selector>();
|
||||||
|
test<gui2::tmp_change_control>();
|
||||||
test<gui2::tmp_cmd_wrapper>();
|
test<gui2::tmp_cmd_wrapper>();
|
||||||
test<gui2::tmp_connect>();
|
test<gui2::tmp_connect>();
|
||||||
test<gui2::tmp_create_game>();
|
test<gui2::tmp_create_game>();
|
||||||
|
@ -566,6 +568,15 @@ struct twrapper<gui2::tmessage>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct twrapper<gui2::tmp_change_control>
|
||||||
|
{
|
||||||
|
static gui2::tmp_change_control* create()
|
||||||
|
{
|
||||||
|
return new gui2::tmp_change_control(NULL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct twrapper<gui2::tmp_cmd_wrapper>
|
struct twrapper<gui2::tmp_cmd_wrapper>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue