The Battle for Wesnoth  1.17.6+dev
lobby_player_list_helper.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2022
3  by Tomasz Sniatowski <kailoran@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 
17 
18 #include "font/text_formatting.hpp"
20 #include "gettext.hpp"
23 #include "gui/widgets/label.hpp"
26 #include "gui/widgets/window.hpp"
27 
28 static lg::log_domain log_lobby("lobby");
29 #define ERR_LB LOG_STREAM(err, log_lobby)
30 
31 namespace gui2
32 {
33 lobby_player_list_helper::sub_list::sub_list(tree_view* parent_tree, const std::string& lbl, const bool unfolded)
34 {
35  widget_data tree_group_item;
36  tree_group_item["tree_view_node_label"]["label"] = lbl;
37 
38  root = &parent_tree->add_node("player_group", tree_group_item);
39 
40  if(unfolded) {
41  root->unfold();
42  }
43 
44  label_player_count = find_widget<label>(root, "player_count", false, true);
45  assert(label_player_count);
46 }
47 
49 {
50  label_player_count->set_label(std::to_string(root->count_children()));
51 }
52 
53 namespace
54 {
55 struct update_pod
56 {
57  /** The raw data used to mass-construct player tree nodes. */
58  std::vector<widget_data> node_data;
59 
60  /** The associated user data for each node, index-to-index. */
61  std::vector<const mp::user_info*> user_data;
62 };
63 } // namespace
64 
65 void lobby_player_list_helper::update(const std::vector<mp::user_info>& user_info, int focused_game)
66 {
67  const unsigned scrollbar_position = tree->get_vertical_scrollbar_item_position();
68  std::array<update_pod, std::tuple_size<decltype(player_lists)>::value> inputs{};
69 
70  for(const auto& user : user_info) {
71  std::string name = user.name;
72 
73  std::stringstream icon_ss;
74  icon_ss << "lobby/status";
75 
76  switch(user.get_state(focused_game)) {
78  icon_ss << "-lobby";
79  break;
81  name = font::span_color({0, 255, 255}, name);
82  icon_ss << (user.observing ? "-obs" : "-playing");
83  break;
85  name = font::span_color(font::GRAY_COLOR, name);
86  icon_ss << (user.observing ? "-obs" : "-playing");
87  break;
88  }
89 
90  switch(user.get_relation()) {
92  icon_ss << "-s";
93  break;
95  icon_ss << "-n";
96  break;
98  icon_ss << "-f";
99  break;
101  icon_ss << "-i";
102  break;
103  }
104 
105  icon_ss << ".png";
106 
107  widget_item tree_group_field;
108  widget_data tree_group_item;
109 
110  /*** Add tree item ***/
111  tree_group_field["label"] = icon_ss.str();
112  tree_group_item["icon"] = tree_group_field;
113 
114  tree_group_field["label"] = name;
115  tree_group_field["use_markup"] = "true";
116  tree_group_item["name"] = tree_group_field;
117 
118  // Indices here must match the order of the lists in the player_lists array (see `init`)
119  switch(user.get_state(focused_game)) {
121  inputs[0].node_data.push_back(std::move(tree_group_item));
122  inputs[0].user_data.push_back(&user);
123 
124  break;
126  inputs[1].node_data.push_back(std::move(tree_group_item));
127  inputs[1].user_data.push_back(&user);
128 
129  break;
131  inputs[2].node_data.push_back(std::move(tree_group_item));
132  inputs[2].user_data.push_back(&user);
133 
134  break;
135  }
136  }
137 
138  for(std::size_t i = 0; i < player_lists.size(); ++i) {
139  assert(inputs[i].node_data.size() == inputs[i].user_data.size());
140 
141  // Add the player nodes
142  const auto new_nodes = player_lists[i].root->replace_children("player", inputs[i].node_data);
143 
144  for(std::size_t k = 0; k < new_nodes.size(); ++k) {
146  find_widget<toggle_panel>(new_nodes[k].get(), "tree_view_node_label", false),
147  std::bind(user_callback, inputs[i].user_data[k])
148  );
149  }
150 
151  player_lists[i].update_player_count_label();
152  }
153 
154  // Don't attempt to restore the scroll position if the window hasn't been laid out yet
155  if(tree->get_origin() != point{-1, -1}) {
156  tree->set_vertical_scrollbar_item_position(scrollbar_position);
157  }
158 }
159 
161 {
162  tree = find_widget<tree_view>(&w, "player_tree", false, true);
163 
164  player_lists = {
165  sub_list{tree, _("Selected Game"), true},
166  sub_list{tree, _("Lobby"), true},
167  sub_list{tree, _("Other Games"), false}
168  };
169 }
170 } // namespace gui2
const color_t GRAY_COLOR
tree_view * tree
The parent tree.
tree_view_node & add_node(const std::string &id, const widget_data &data, const int index=-1)
Definition: tree_view.cpp:57
This file contains the window object, this object is a top level container which has the event manage...
static std::string _(const char *str)
Definition: gettext.hpp:93
std::size_t count_children() const
The number of children in this widget.
Generic file dialog.
virtual void set_label(const t_string &label)
std::string span_color(const color_t &color)
Returns a Pango formatting string using the provided color_t object.
std::vector< const mp::user_info * > user_data
The associated user data for each node, index-to-index.
std::map< std::string, t_string > widget_item
Definition: widget.hpp:32
static lg::log_domain log_lobby("lobby")
A tree view is a control that holds several items of the same or different types. ...
Definition: tree_view.hpp:60
std::array< sub_list, 3 > player_lists
Main subsections of the player tree.
std::function< void(const mp::user_info *)> user_callback
The double click callback bound to each player&#39;s tree node.
std::vector< widget_data > node_data
The raw data used to mass-construct player tree nodes.
std::size_t i
Definition: function.cpp:967
void set_vertical_scrollbar_item_position(const unsigned position)
Move the vertical scrollbar to a position.
Holds a 2D point.
Definition: point.hpp:24
void unfold(const bool recursive=false)
int w
void connect_signal_mouse_left_double_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button double click.
Definition: dispatcher.cpp:200
unsigned get_vertical_scrollbar_item_position() const
Returns current position of the vertical scrollbar.
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
void update(const std::vector< mp::user_info > &user_info, int focused_game)
Updates the tree contents based on the given user data.
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:66
point get_origin() const
Returns the screen origin of the widget.
Definition: widget.cpp:301