The Battle for Wesnoth  1.19.5+dev
mp_change_control.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2024
3  by Lukasz Dobrogowski <lukasz.dobrogowski@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
19 
20 #include "serialization/markup.hpp"
21 #include "formatter.hpp"
22 #include "formula/string_utils.hpp"
23 #include "game_board.hpp"
24 #include "game_display.hpp"
26 #include "gui/widgets/label.hpp"
27 #include "gui/widgets/listbox.hpp"
28 #include "gui/widgets/window.hpp"
29 #include "log.hpp"
30 #include "menu_events.hpp"
31 #include "serialization/markup.hpp"
32 #include "team.hpp"
33 
34 #include <functional>
35 
36 static lg::log_domain log_gui("gui/dialogs/mp_change_control");
37 #define ERR_GUI LOG_STREAM(err, log_gui)
38 #define WRN_GUI LOG_STREAM(warn, log_gui)
39 #define LOG_GUI LOG_STREAM(info, log_gui)
40 #define DBG_GUI LOG_STREAM(debug, log_gui)
41 
42 namespace gui2::dialogs
43 {
44 
45 REGISTER_DIALOG(mp_change_control)
46 
48  : modal_dialog(window_id())
49  , menu_handler_(mh)
50  , selected_side_(0)
51  , selected_nick_(0)
52  , sides_()
53  , nicks_()
54 {
55 }
56 
58 {
59  listbox& sides_list = find_widget<listbox>("sides_list");
60  listbox& nicks_list = find_widget<listbox>("nicks_list");
61 
64 
67 
68  //
69  // Initialize sides list
70  //
71  for(const team& t : menu_handler_.board().teams()) {
72  if(t.hidden()) {
73  continue;
74  }
75 
76  const int side = sides_.emplace_back(t.side());
77 
79  widget_item item;
80 
81  std::string side_str = VGETTEXT("Side $side", {{"side", std::to_string(side)}});
82  side_str = markup::span_color(team::get_side_color(side), side_str);
83 
84  item["id"] = (formatter() << "side_" << side).str();
85  item["label"] = side_str;
86  item["use_markup"] = "true";
87  data.emplace("side", item);
88 
89  sides_list.add_row(data);
90  }
91 
92  //
93  // Prepare set of available nicknames
94  //
95  std::set<std::string> temp_nicks;
96  for(const auto& team : menu_handler_.board().teams()) {
97  if(!team.is_local_ai() && !team.is_network_ai() && !team.is_idle()
98  && !team.is_empty() && !team.current_player().empty())
99  {
100  temp_nicks.insert(team.current_player());
101  }
102  }
103 
104  const std::set<std::string>& observers = game_display::get_singleton()->observers();
105  temp_nicks.insert(observers.begin(), observers.end());
106 
107  // In case we are an observer, it isn't in the observers set and has to be added manually.
108  temp_nicks.insert(prefs::get().login());
109 
110  //
111  // Initialize nick list
112  //
113  for(const std::string& nick : temp_nicks) {
114  nicks_.push_back(nick);
115 
117  widget_item item;
118 
119  item["id"] = nick;
120  item["label"] = nick;
121  item["use_markup"] = "true";
122  data.emplace("nick", item);
123 
124  nicks_list.add_row(data);
125  }
126 
129 }
130 
132 {
133  selected_side_ = find_widget<listbox>("sides_list").get_selected_row();
134 
136 }
137 
139 {
140  selected_nick_ = find_widget<listbox>("nicks_list").get_selected_row();
141 }
142 
144 {
145  listbox& nicks_list = find_widget<listbox>("nicks_list");
146  const auto& teams = menu_handler_.board().teams();
147 
148  int i = 0;
149  for(const std::string& nick : nicks_) {
150  std::string label_str = "";
151 
152  if(selected_side_ <= static_cast<unsigned int>(teams.size()) && teams.at(selected_side_).current_player() == nick) {
153  label_str = markup::bold(nick);
154  } else {
155  label_str = nick;
156  }
157 
158  grid* row_grid = nicks_list.get_row_grid(i);
159  row_grid->find_widget<label>(nick).set_label(label_str);
160 
161  ++i;
162  }
163 }
164 
166 {
167  if(get_retval() == retval::OK) {
168  DBG_GUI << "Main: changing control of side "
169  << sides_[selected_side_] << " to nick "
171 
175  );
176  }
177 }
178 
179 } // namespace dialogs
double t
Definition: astarsearch.cpp:63
game_board & board() const
void request_control_change(int side_num, const std::string &player)
std::ostringstream wrapper.
Definition: formatter.hpp:40
virtual const std::vector< team > & teams() const override
Definition: game_board.hpp:80
virtual const std::set< std::string > & observers() const override
static game_display * get_singleton()
Abstract base class for all modal dialogs.
int get_retval() const
Returns the cached window exit code.
std::vector< std::string > nicks_
virtual void pre_show() override
Actions to be taken before showing the window.
virtual void post_show() override
Actions to be taken after the window has been shown.
events::menu_handler & menu_handler_
Base container class.
Definition: grid.hpp:32
The listbox class.
Definition: listbox.hpp:43
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition: listbox.cpp:58
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
Definition: listbox.cpp:229
virtual void set_label(const t_string &text)
NOT_DANGLING T * find_widget(const std::string &id, const bool must_be_active, const bool must_exist)
Gets a widget with the wanted id.
Definition: widget.hpp:742
static prefs & get()
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
const std::string & current_player() const
Definition: team.hpp:220
bool is_network_ai() const
Definition: team.hpp:256
bool is_local_ai() const
Definition: team.hpp:254
bool is_idle() const
Definition: team.hpp:270
static color_t get_side_color(int side)
Definition: team.cpp:960
bool is_empty() const
Definition: team.hpp:245
#define VGETTEXT(msgid,...)
Handy wrappers around interpolate_variables_into_string and gettext.
std::size_t i
Definition: function.cpp:1028
This file contains the window object, this object is a top level container which has the event manage...
Standard logging facilities (interface).
#define DBG_GUI
static lg::log_domain log_gui("gui/dialogs/mp_change_control")
Handling of system events.
REGISTER_DIALOG(editor_edit_unit)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:203
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:36
std::map< std::string, t_string > widget_item
Definition: widget.hpp:33
@ OK
Dialog was closed with the OK button.
Definition: retval.hpp:35
std::string bold(Args &&... data)
Definition: markup.hpp:128
std::string span_color(const color_t &color, Args &&... data)
Definition: markup.hpp:68
std::string_view data
Definition: picture.cpp:178