The Battle for Wesnoth  1.17.12+dev
achievements_dialog.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
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 "game_config_manager.hpp"
21 #include "gettext.hpp"
23 #include "gui/widgets/grid.hpp"
24 #include "gui/widgets/label.hpp"
26 #include "gui/widgets/window.hpp"
27 #include "log.hpp"
28 
29 namespace gui2::dialogs
30 {
31 
33 
35 
37  : modal_dialog(window_id())
38  , achieve_()
39  , achievements_box_(nullptr)
40  , content_names_(nullptr)
41 {
42 }
43 
45 {
46  std::vector<config> content_list;
47  content_names_ = &find_widget<menu_button>(&win, "selected_achievements_list", false);
49 
50  achievements_box_ = find_widget<listbox>(&win, "achievements_list", false, true);
51 
52  std::vector<achievement_group> groups = game_config_manager::get()->get_achievements();
53  // reset the selected achievement group in case add-ons with achievements are uninstalled between closing and re-opening the dialog
54  if(selected_index_ > groups.size()) {
55  selected_index_ = 0;
56  }
57 
58  for(const auto& list : groups) {
59  // only display the achievements for the first dropdown option on first showing the dialog
60  if(content_list.size() == selected_index_) {
61  int achieved_count = 0;
62 
63  for(const auto& ach : list.achievements_) {
64  widget_data row;
66 
67  if(ach.achieved_) {
68  achieved_count++;
69  }
70 
71  item["label"] = !ach.achieved_ ? ach.icon_ : ach.icon_completed_;
72  row.emplace("icon", item);
73 
74  if(ach.hidden_ && !ach.achieved_) {
75  item["label"] = ach.hidden_name_;
76  } else if(!ach.achieved_) {
77  std::string name = ach.name_;
78  if(ach.max_progress_ != 0 && ach.current_progress_ != -1) {
79  name += " ("+std::to_string(ach.current_progress_)+"/"+std::to_string(ach.max_progress_)+")";
80  }
81  item["label"] = name;
82  } else {
83  item["label"] = "<span color='green'>"+ach.name_completed_+"</span>";
84  }
85  row.emplace("name", item);
86 
87  if(ach.hidden_ && !ach.achieved_) {
88  item["label"] = ach.hidden_hint_;
89  } else if(!ach.achieved_) {
90  item["label"] = ach.description_;
91  } else {
92  item["label"] = "<span color='green'>"+ach.description_completed_+"</span>";
93  }
94  row.emplace("description", item);
95 
96  grid& newrow = achievements_box_->add_row(row);
97  progress_bar* achievement_progress = static_cast<progress_bar*>(newrow.find("achievement_progress", false));
98  if(ach.max_progress_ != 0 && ach.current_progress_ != -1) {
99  achievement_progress->set_percentage((ach.current_progress_/double(ach.max_progress_))*100);
100  } else {
101  achievement_progress->set_visible(gui2::widget::visibility::invisible);
102  }
103  }
104 
105  label* achieved_label = find_widget<label>(&win, "achievement_count", false, true);
106  achieved_label->set_label(_("Completed")+" "+std::to_string(achieved_count)+"/"+std::to_string(list.achievements_.size()));
107  }
108 
109  // populate all possibilities into the dropdown
110  content_list.emplace_back("label", list.display_name_);
111  }
112  if(content_list.size() > 0) {
113  content_names_->set_values(content_list);
115  }
116 }
117 
119 {
120 }
121 
123 {
125  int achieved_count = 0;
127 
129  for(const auto& ach : list.achievements_) {
130  widget_data row;
132 
133  if(ach.achieved_) {
134  achieved_count++;
135  }
136 
137  item["label"] = !ach.achieved_ ? ach.icon_ : ach.icon_completed_;
138  row.emplace("icon", item);
139 
140  if(ach.hidden_ && !ach.achieved_) {
141  item["label"] = ach.hidden_name_;
142  } else if(!ach.achieved_) {
143  item["label"] = ach.name_;
144  } else {
145  item["label"] = "<span color='green'>"+ach.name_completed_+"</span>";
146  }
147  row.emplace("name", item);
148 
149  if(ach.hidden_ && !ach.achieved_) {
150  item["label"] = ach.hidden_hint_;
151  } else if(!ach.achieved_) {
152  item["label"] = ach.description_;
153  } else {
154  item["label"] = "<span color='green'>"+ach.description_completed_+"</span>";
155  }
156  row.emplace("description", item);
157 
158  grid& newrow = achievements_box_->add_row(row);
159  progress_bar* achievement_progress = static_cast<progress_bar*>(newrow.find("achievement_progress", false));
160  if(ach.max_progress_ != 0 && ach.current_progress_ != -1) {
161  achievement_progress->set_percentage((ach.current_progress_/double(ach.max_progress_))*100);
162  } else {
163  achievement_progress->set_visible(gui2::widget::visibility::invisible);
164  }
165  }
166 
167  label* achieved_label = find_widget<label>(get_window(), "achievement_count", false, true);
168  achieved_label->set_label(_("Completed")+" "+std::to_string(achieved_count)+"/"+std::to_string(list.achievements_.size()));
169 }
170 
171 } // namespace gui2::dialogs
void set_selected(unsigned selected, bool fire_event=true)
std::vector< achievement > achievements_
The achievements associated to this content.
void set_percentage(unsigned percentage)
This file contains the window object, this object is a top level container which has the event manage...
This object shows the progress of a certain action, or the value state of a certain item...
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:61
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:57
static std::string _(const char *str)
Definition: gettext.hpp:93
virtual void set_label(const t_string &label)
This shows a dialog displaying achievements.
Base container class.
Definition: grid.hpp:31
static game_config_manager * get()
virtual unsigned get_value() const override
Inherited from selectable_item.
Definition: menu_button.hpp:84
std::map< std::string, t_string > widget_item
Definition: widget.hpp:32
std::vector< achievement_group > & get_achievements()
void clear()
Removes all the rows in the listbox, clearing it.
Definition: listbox.cpp:120
void set_visible(const visibility visible)
Definition: widget.cpp:456
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Definition: grid.cpp:645
void set_values(const std::vector<::config > &values, unsigned selected=0)
window * get_window()
Returns a pointer to the dialog&#39;s window.
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
The user set the widget invisible, that means:
Abstract base class for all modal dialogs.
Standard logging facilities (interface).
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
A set of achievements tied to a particular content.
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:66
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:205
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
static unsigned int selected_index_
variable of the most recently selected achievements, static to persist between closing and re-opening...