The Battle for Wesnoth  1.17.23+dev
achievements_dialog.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2023
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/drawing.hpp"
24 #include "gui/widgets/grid.hpp"
25 #include "gui/widgets/label.hpp"
27 #include "gui/widgets/window.hpp"
28 #include "log.hpp"
29 #include "preferences/general.hpp"
30 
31 static lg::log_domain log_config("config");
32 #define ERR_CONFIG LOG_STREAM(err, log_config)
33 
34 constexpr int sub_achievements_limit = 28;
35 
36 namespace gui2::dialogs
37 {
38 
40 
42  : modal_dialog(window_id())
43  , achieve_()
44  , last_selected_(preferences::selected_achievement_group())
45  , achievements_box_(nullptr)
46  , content_names_(nullptr)
47 {
48 }
49 
51 {
52  std::vector<config> content_list;
53  content_names_ = &find_widget<menu_button>(&win, "selected_achievements_list", false);
55 
56  achievements_box_ = find_widget<listbox>(&win, "achievements_list", false, true);
57 
58  std::vector<achievement_group> groups = game_config_manager::get()->get_achievements();
59  int selected = 0;
60 
61  for(const auto& list : groups) {
62  // only display the achievements for the first dropdown option on first showing the dialog
63  if(list.content_for_ == last_selected_ || last_selected_ == "") {
64  selected = content_list.size();
65  }
66 
67  // populate all possibilities into the dropdown
68  content_list.emplace_back("label", list.display_name_);
69  }
70 
71  if(content_list.size() > 0) {
72  content_names_->set_values(content_list);
75  }
76 }
77 
79 {
81 }
82 
84 {
88  int achieved_count = 0;
89 
90  for(const auto& ach : list.achievements_) {
91  if(ach.achieved_) {
92  achieved_count++;
93  } else if(ach.hidden_ && !ach.achieved_) {
94  continue;
95  }
96 
97  widget_data row;
99 
100  item["label"] = !ach.achieved_ ? ach.icon_ : ach.icon_completed_;
101  row.emplace("icon", item);
102 
103  if(!ach.achieved_) {
104  t_string name = ach.name_;
105  if(ach.max_progress_ != 0 && ach.current_progress_ != -1) {
106  name += " ("+std::to_string(ach.current_progress_)+"/"+std::to_string(ach.max_progress_)+")";
107  }
108  item["label"] = name;
109  } else {
110  item["label"] = ach.name_completed_;
111  item["definition"] = "gold_large";
112  }
113  row.emplace("name", item);
114 
115  if(!ach.achieved_) {
116  item["label"] = ach.description_;
117  } else {
118  item["label"] = "<span color='green'>"+ach.description_completed_+"</span>";
119  }
120  row.emplace("description", item);
121 
122  grid& newrow = achievements_box_->add_row(row);
123  progress_bar* achievement_progress = static_cast<progress_bar*>(newrow.find("achievement_progress", false));
124  if(ach.max_progress_ != 0 && ach.current_progress_ != -1) {
125  achievement_progress->set_percentage((ach.current_progress_/double(ach.max_progress_))*100);
126  } else {
127  achievement_progress->set_visible(gui2::widget::visibility::invisible);
128  }
129 
130  label* name = static_cast<label*>(newrow.find("name", false));
131  canvas& canvas = name->get_canvas(0);
132  canvas.set_variable("achieved", wfl::variant(ach.achieved_));
133 
134  set_sub_achievements(newrow, ach);
135  }
136 
137  label* achieved_label = find_widget<label>(get_window(), "achievement_count", false, true);
138  achieved_label->set_label(_("Completed")+" "+std::to_string(achieved_count)+"/"+std::to_string(list.achievements_.size()));
139 }
140 
142 {
143  int i = 0;
144 
145  // set any sub achievements
146  for(const sub_achievement& sub_ach : ach.sub_achievements_)
147  {
149  {
150  ERR_CONFIG << "Too many sub achievements";
151  break;
152  }
153  else
154  {
155  drawing* img = static_cast<drawing*>(newrow.find("sub_icon"+std::to_string(i), false));
156  img->set_label(sub_ach.achieved_ ? sub_ach.icon_completed_ : sub_ach.icon_);
157  img->set_tooltip(sub_ach.description_);
158  }
159  i++;
160  }
161 
162  // if an achievement hasn't defined the maximum possible sub-achievements, hide the [image]s for the rest
163  for(; i < sub_achievements_limit; i++)
164  {
165  static_cast<drawing*>(newrow.find("sub_icon"+std::to_string(i), false))->set_visible(visibility::invisible);
166  }
167 }
168 
169 } // namespace gui2::dialogs
constexpr int sub_achievements_limit
#define ERR_CONFIG
static lg::log_domain log_config("config")
static game_config_manager * get()
std::vector< achievement_group > & get_achievements()
A simple canvas which can be drawn upon.
Definition: canvas.hpp:45
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:154
This shows a dialog displaying achievements.
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
void set_sub_achievements(grid &newrow, const achievement &ach)
Abstract base class for all modal dialogs.
window * get_window()
Returns a pointer to the dialog's window.
A drawing is widget with a fixed size and gives access to the canvas of the widget in the window inst...
Definition: drawing.hpp:53
Base container class.
Definition: grid.hpp:32
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Definition: grid.cpp:645
A label displays text that can be wrapped but no scrollbars are provided.
Definition: label.hpp:57
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:62
void clear()
Removes all the rows in the listbox, clearing it.
Definition: listbox.cpp:121
void set_selected(unsigned selected, bool fire_event=true)
void set_values(const std::vector<::config > &values, unsigned selected=0)
virtual unsigned get_value() const override
Inherited from selectable_item.
Definition: menu_button.hpp:84
This object shows the progress of a certain action, or the value state of a certain item.
void set_percentage(unsigned percentage)
void set_tooltip(const t_string &tooltip)
virtual void set_label(const t_string &label)
canvas & get_canvas(const unsigned index)
void set_visible(const visibility visible)
Definition: widget.cpp:471
@ invisible
The user set the widget invisible, that means:
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:67
std::size_t i
Definition: function.cpp:968
static std::string _(const char *str)
Definition: gettext.hpp:93
This file contains the window object, this object is a top level container which has the event manage...
Standard logging facilities (interface).
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
std::string selected
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::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
std::map< std::string, t_string > widget_item
Definition: widget.hpp:32
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
Modify, read and display user preferences.
std::string selected_achievement_group()
Definition: general.cpp:1019
void set_selected_achievement_group(const std::string &content_for)
Definition: general.cpp:1024
A set of achievements tied to a particular content.
std::string content_for_
The internal ID used for this content.
std::vector< achievement > achievements_
The achievements associated to this content.
Represents a single achievement and its data.
std::vector< sub_achievement > sub_achievements_
The list of distinct sub-achievements for this achievement.
Represents a distinct sub-achievement within another achievement.
t_string description_
The description of the sub-achievement to be shown in its tooltip.
std::string icon_completed_
The icon of the sub-achievement to show on the UI when completed.
std::string icon_
The icon of the sub-achievement to show on the UI when not completed.
bool achieved_
Whether the sub-achievement has been completed.