Converted Recall dialog to GUI2
This also includes the appropriate expansions and design updates to the unit_preview_pane widget.
This commit is contained in:
parent
a515dd403a
commit
105fbe6bc6
11 changed files with 632 additions and 331 deletions
|
@ -7,9 +7,9 @@
|
|||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
border = "bottom"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "center"
|
||||
horizontal_alignment = "left"
|
||||
vertical_alignment = "center"
|
||||
|
||||
[image]
|
||||
|
@ -20,30 +20,11 @@
|
|||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
border = "bottom"
|
||||
border_size = 5
|
||||
horizontal_alignment = "center"
|
||||
|
||||
[button]
|
||||
id = "type_profile"
|
||||
definition = "default"
|
||||
|
||||
label = _ "Profile"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
[column]
|
||||
border = "bottom"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
vertical_grow = "true"
|
||||
horizontal_grow = "true"
|
||||
|
@ -61,6 +42,7 @@
|
|||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
horizontal_grow = "true"
|
||||
|
||||
[grid]
|
||||
|
@ -69,7 +51,8 @@
|
|||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
border = "right,bottom"
|
||||
grow_factor = 0
|
||||
border = "left,right"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
|
@ -80,7 +63,8 @@
|
|||
[/column]
|
||||
|
||||
[column]
|
||||
border = "right,bottom"
|
||||
grow_factor = 0
|
||||
border = "left,right"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
|
@ -91,7 +75,8 @@
|
|||
[/column]
|
||||
|
||||
[column]
|
||||
border = "bottom"
|
||||
grow_factor = 0
|
||||
border = "left,right"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
|
@ -100,6 +85,21 @@
|
|||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
border = "left,right"
|
||||
border_size = 5
|
||||
horizontal_alignment = "right"
|
||||
|
||||
[button]
|
||||
id = "type_profile"
|
||||
definition = "action_about"
|
||||
|
||||
label = _ "Profile"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
|
@ -115,6 +115,8 @@
|
|||
[column]
|
||||
vertical_grow = "true"
|
||||
horizontal_alignment = "left"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "type_details"
|
||||
|
@ -289,8 +291,8 @@
|
|||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "type_details"
|
||||
definition = "default"
|
||||
id = "type_details_minimal"
|
||||
definition = "default_small"
|
||||
|
||||
text_alignment = "right"
|
||||
[/label]
|
||||
|
@ -348,8 +350,8 @@
|
|||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "type_details"
|
||||
definition = "default"
|
||||
id = "type_details_minimal"
|
||||
definition = "default_small"
|
||||
|
||||
text_alignment = "left"
|
||||
[/label]
|
||||
|
|
|
@ -627,6 +627,8 @@
|
|||
<Unit filename="../../src/gui/dialogs/unit_attack.hpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_create.cpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_create.hpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_recall.cpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_recall.hpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_recruit.cpp" />
|
||||
<Unit filename="../../src/gui/dialogs/unit_recruit.hpp" />
|
||||
<Unit filename="../../src/gui/dialogs/wml_error.cpp" />
|
||||
|
|
|
@ -843,6 +843,7 @@ set(wesnoth-main_SRC
|
|||
gui/dialogs/transient_message.cpp
|
||||
gui/dialogs/unit_attack.cpp
|
||||
gui/dialogs/unit_create.cpp
|
||||
gui/dialogs/unit_recall.cpp
|
||||
gui/dialogs/unit_recruit.cpp
|
||||
gui/dialogs/wml_error.cpp
|
||||
gui/dialogs/wml_message.cpp
|
||||
|
|
|
@ -420,6 +420,7 @@ wesnoth_sources = Split("""
|
|||
gui/dialogs/transient_message.cpp
|
||||
gui/dialogs/unit_attack.cpp
|
||||
gui/dialogs/unit_create.cpp
|
||||
gui/dialogs/unit_recall.cpp
|
||||
gui/dialogs/unit_recruit.cpp
|
||||
gui/dialogs/wml_error.cpp
|
||||
gui/dialogs/wml_message.cpp
|
||||
|
|
225
src/dialogs.cpp
225
src/dialogs.cpp
|
@ -39,7 +39,6 @@
|
|||
#include "menu_events.hpp"
|
||||
#include "mouse_handler_base.hpp"
|
||||
#include "minimap.hpp"
|
||||
#include "recall_list_manager.hpp"
|
||||
#include "replay.hpp"
|
||||
#include "replay_helper.hpp"
|
||||
#include "resources.hpp"
|
||||
|
@ -83,90 +82,6 @@ static lg::log_domain log_config("config");
|
|||
namespace dialogs
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class delete_recall_unit : public gui::dialog_button_action
|
||||
{
|
||||
public:
|
||||
delete_recall_unit(display& disp, gui::filter_textbox& filter, const std::shared_ptr<std::vector<unit_const_ptr > >& units) : disp_(disp), filter_(filter), units_(units) {}
|
||||
private:
|
||||
gui::dialog_button_action::RESULT button_pressed(int menu_selection);
|
||||
|
||||
display& disp_;
|
||||
gui::filter_textbox& filter_;
|
||||
std::shared_ptr<std::vector<unit_const_ptr > > units_;
|
||||
};
|
||||
|
||||
template<typename T> void dump(const T & units)
|
||||
{
|
||||
log_scope2(log_display, "dump()")
|
||||
|
||||
LOG_DP << "size: " << units.size() << "\n";
|
||||
size_t idx = 0;
|
||||
for (const unit_const_ptr & u_ptr : units) {
|
||||
LOG_DP << "unit[" << (idx++) << "]: " << u_ptr->id() << " name = '" << u_ptr->name() << "'\n";
|
||||
}
|
||||
}
|
||||
|
||||
gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_selection)
|
||||
{
|
||||
const size_t index = size_t(filter_.get_index(menu_selection));
|
||||
|
||||
LOG_DP << "units_:\n"; dump(*units_);
|
||||
if(index < units_->size()) {
|
||||
const unit_const_ptr & u_ptr = units_->at(index);
|
||||
const unit & u = *u_ptr;
|
||||
|
||||
//If the unit is of level > 1, or is close to advancing,
|
||||
//we warn the player about it
|
||||
std::stringstream message;
|
||||
if (u.loyal()) {
|
||||
// TRANSLATORS: this string ends with a space
|
||||
message << _("This unit is loyal and requires no upkeep. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
} else if(u.level() > 1) {
|
||||
// TRANSLATORS: this string ends with a space
|
||||
message << _("This unit is an experienced one, having advanced levels. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
|
||||
} else if(u.experience() > u.max_experience()/2) {
|
||||
// TRANSLATORS: this string ends with a space
|
||||
message << _("This unit is close to advancing a level. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
}
|
||||
|
||||
if(!message.str().empty()) {
|
||||
const int res = gui2::show_message(disp_.video(), _("Dismiss Unit"), message.str(), gui2::tmessage::yes_no_buttons);
|
||||
if(res == gui2::twindow::CANCEL) {
|
||||
return gui::CONTINUE_DIALOG;
|
||||
}
|
||||
}
|
||||
// Remove the item from our dialog's list
|
||||
units_->erase(units_->begin() + index);
|
||||
|
||||
// Remove the item from filter_textbox memory
|
||||
filter_.delete_item(menu_selection);
|
||||
|
||||
LOG_DP << "Dismissing a unit, side = " << u.side() << " id = '" << u.id() << "'\n";
|
||||
LOG_DP << "That side's recall list:\n";
|
||||
dump((*resources::teams)[u.side() -1].recall_list());
|
||||
|
||||
// Find the unit in the recall list.
|
||||
unit_ptr dismissed_unit = (*resources::teams)[u.side() -1].recall_list().find_if_matches_id(u.id());
|
||||
assert(dismissed_unit);
|
||||
|
||||
// Record the dismissal, then delete the unit.
|
||||
synced_context::run_and_throw("disband", replay_helper::get_disband(dismissed_unit->id()));
|
||||
|
||||
return gui::DELETE_ITEM;
|
||||
} else {
|
||||
return gui::CONTINUE_DIALOG;
|
||||
}
|
||||
}
|
||||
|
||||
} //anon namespace
|
||||
|
||||
int advance_unit_dialog(const map_location &loc)
|
||||
{
|
||||
unit_map::iterator u = resources::units->find(loc);
|
||||
|
@ -427,146 +342,6 @@ void show_objectives(const std::string &scenarioname, const std::string &objecti
|
|||
(objectives.empty() ? no_objectives : objectives), "", true);
|
||||
}
|
||||
|
||||
#ifdef LOW_MEM
|
||||
int recall_dialog(display& disp, const std::shared_ptr<std::vector< unit_const_ptr > > & units, int /*side*/, const std::string& title_suffix, const int team_recall_cost)
|
||||
#else
|
||||
int recall_dialog(display& disp, const std::shared_ptr<std::vector< unit_const_ptr > > & units, int side, const std::string& title_suffix, const int team_recall_cost)
|
||||
#endif
|
||||
{
|
||||
std::vector<std::string> options, options_to_filter;
|
||||
|
||||
std::ostringstream heading;
|
||||
heading << HEADING_PREFIX << COLUMN_SEPARATOR << _("Type")
|
||||
<< COLUMN_SEPARATOR << _("Name")
|
||||
<< COLUMN_SEPARATOR << _("Level^Lvl.")
|
||||
<< COLUMN_SEPARATOR << _("XP");
|
||||
heading << COLUMN_SEPARATOR << _("Traits");
|
||||
|
||||
gui::menu::basic_sorter sorter;
|
||||
sorter.set_alpha_sort(1).set_alpha_sort(2);
|
||||
sorter.set_level_sort(3,4).set_xp_sort(4).set_alpha_sort(5);
|
||||
|
||||
options.push_back(heading.str());
|
||||
options_to_filter.push_back(options.back());
|
||||
|
||||
for (const unit_const_ptr & u : *units)
|
||||
{
|
||||
std::stringstream option, option_to_filter;
|
||||
std::string name = u->name();
|
||||
if (name.empty()) name = utils::unicode_em_dash;
|
||||
|
||||
option << IMAGE_PREFIX << u->absolute_image();
|
||||
|
||||
#ifndef LOW_MEM
|
||||
option << "~RC(" << u->team_color() << '>'
|
||||
<< team::get_side_color_index(side) << ')';
|
||||
|
||||
if(u->can_recruit()) {
|
||||
option << "~BLIT(" << unit::leader_crown() << ")";
|
||||
}
|
||||
|
||||
for(const std::string& overlay : u->overlays())
|
||||
{
|
||||
option << "~BLIT(" << overlay << ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
option << COLUMN_SEPARATOR;
|
||||
int cost = u->recall_cost();
|
||||
if(cost < 0) {
|
||||
cost = team_recall_cost;
|
||||
}
|
||||
option << u->type_name() << "\n";
|
||||
if(cost > team_recall_cost) {
|
||||
option << font::NORMAL_TEXT << "<255,0,0>";
|
||||
}
|
||||
else if(cost == team_recall_cost) {
|
||||
option << font::NORMAL_TEXT;
|
||||
}
|
||||
else if(cost < team_recall_cost) {
|
||||
option << font::NORMAL_TEXT << "<0,255,0>";
|
||||
}
|
||||
option << cost << " Gold" << COLUMN_SEPARATOR
|
||||
<< name << COLUMN_SEPARATOR;
|
||||
|
||||
// Show units of level (0=gray, 1 normal, 2 bold, 2+ bold&wbright)
|
||||
const int level = u->level();
|
||||
if(level < 1) {
|
||||
option << "<150,150,150>";
|
||||
} else if(level == 1) {
|
||||
option << font::NORMAL_TEXT;
|
||||
} else if(level == 2) {
|
||||
option << font::BOLD_TEXT;
|
||||
} else if(level > 2 ) {
|
||||
option << font::BOLD_TEXT << "<255,255,255>";
|
||||
}
|
||||
option << level << COLUMN_SEPARATOR;
|
||||
|
||||
option << font::color2markup(u->xp_color()) << u->experience() << "/";
|
||||
if (u->can_advance())
|
||||
option << u->max_experience();
|
||||
else
|
||||
option << "-";
|
||||
|
||||
option_to_filter << u->type_name() << " " << name << " " << u->level();
|
||||
|
||||
option << COLUMN_SEPARATOR;
|
||||
for(const t_string& trait : u->trait_names()) {
|
||||
option << trait << '\n';
|
||||
option_to_filter << " " << trait;
|
||||
}
|
||||
|
||||
options.push_back(option.str());
|
||||
options_to_filter.push_back(option_to_filter.str());
|
||||
}
|
||||
|
||||
gui::dialog rmenu(disp.video(), _("Recall") + title_suffix,
|
||||
_("Select unit:") + std::string("\n"),
|
||||
gui::OK_CANCEL, gui::dialog::default_style);
|
||||
|
||||
gui::menu::imgsel_style units_display_style(gui::menu::bluebg_style);
|
||||
units_display_style.scale_images(font::relative_size(72), font::relative_size(72));
|
||||
|
||||
gui::menu* units_menu = new gui::menu(disp.video(), options, false, -1,
|
||||
gui::dialog::max_menu_width, &sorter, &units_display_style, false);
|
||||
|
||||
rmenu.set_menu(units_menu);
|
||||
|
||||
gui::filter_textbox* filter = new gui::filter_textbox(disp.video(),
|
||||
_("Filter: "), options, options_to_filter, 1, rmenu, 200);
|
||||
rmenu.set_textbox(filter);
|
||||
|
||||
delete_recall_unit recall_deleter(disp, *filter, units);
|
||||
gui::dialog_button_info delete_button(&recall_deleter,_("Dismiss Unit"));
|
||||
rmenu.add_button(delete_button);
|
||||
|
||||
rmenu.add_button(new help::help_button(disp.video(), "recruit_and_recall"),
|
||||
gui::dialog::BUTTON_HELP);
|
||||
|
||||
dialogs::units_list_preview_pane unit_preview(units, filter);
|
||||
rmenu.add_pane(&unit_preview);
|
||||
|
||||
//sort by level
|
||||
static int sort_by = 3;
|
||||
static bool sort_reversed = false;
|
||||
|
||||
if(sort_by >= 0) {
|
||||
rmenu.get_menu().sort_by(sort_by);
|
||||
// "reclick" on the sorter to reverse the order
|
||||
if(sort_reversed) {
|
||||
rmenu.get_menu().sort_by(sort_by);
|
||||
}
|
||||
}
|
||||
|
||||
int res = rmenu.show();
|
||||
res = filter->get_index(res);
|
||||
|
||||
sort_by = rmenu.get_menu().get_sort_by();
|
||||
sort_reversed = rmenu.get_menu().get_sort_reversed();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
namespace {
|
||||
static const int unit_preview_border = 10;
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ void show_objectives(const std::string& scenarioname, const std::string &objecti
|
|||
|
||||
void show_unit_list(display& gui);
|
||||
|
||||
int recall_dialog(display& disp, const std::shared_ptr<std::vector<unit_const_ptr > > & units, int side, const std::string& title_suffix, const int team_recall_cost);
|
||||
|
||||
/** Show unit-stats in a side-pane to unit-list, recall-list, etc. */
|
||||
class unit_preview_pane : public gui::preview_pane
|
||||
{
|
||||
|
|
399
src/gui/dialogs/unit_recall.cpp
Normal file
399
src/gui/dialogs/unit_recall.cpp
Normal file
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
Copyright (C) 2016 by 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/unit_recall.hpp"
|
||||
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
#include "gui/dialogs/helper.hpp"
|
||||
#include "gui/dialogs/message.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/button.hpp"
|
||||
#include "gui/widgets/image.hpp"
|
||||
#include "gui/widgets/label.hpp"
|
||||
#include "gui/widgets/text_box.hpp"
|
||||
#include "gui/widgets/toggle_button.hpp"
|
||||
#include "gui/widgets/unit_preview_pane.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "help/help.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "replay_helper.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "synced_context.hpp"
|
||||
#include "team.hpp"
|
||||
#include "units/types.hpp"
|
||||
#include "units/unit.hpp"
|
||||
#include "units/ptr.hpp"
|
||||
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define LOG_DP LOG_STREAM(info, log_display)
|
||||
|
||||
namespace gui2
|
||||
{
|
||||
|
||||
REGISTER_DIALOG(unit_recall)
|
||||
|
||||
tunit_recall::tunit_recall(recalls_ptr_vector& recall_list, team& team)
|
||||
: recall_list_(recall_list)
|
||||
, team_(team)
|
||||
, selected_index_()
|
||||
, filter_options_()
|
||||
, last_words_()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void dump_recall_list_to_console(const T& units)
|
||||
{
|
||||
log_scope2(log_display, "dump_recall_list_to_console()")
|
||||
|
||||
LOG_DP << "size: " << units.size() << "\n";
|
||||
|
||||
size_t idx = 0;
|
||||
for(const unit_const_ptr& u_ptr : units) {
|
||||
LOG_DP << "\tunit[" << (idx++) << "]: " << u_ptr->id() << " name = '" << u_ptr->name() << "'\n";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string format_level_string(const int level)
|
||||
{
|
||||
std::string lvl = std::to_string(level);
|
||||
|
||||
if(level < 1) {
|
||||
return "<span color='#969696'>" + lvl + "</span>";
|
||||
} else if(level == 1) {
|
||||
return lvl;
|
||||
} else if(level == 2) {
|
||||
return "<b>" + lvl + "</b>";
|
||||
} else if(level > 2 ) {
|
||||
return"<b><span color='#ffffff'>" + lvl + "</span></b>";
|
||||
}
|
||||
|
||||
return lvl;
|
||||
}
|
||||
|
||||
static std::string format_cost_string(int unit_recall_cost, const int team_recall_cost)
|
||||
{
|
||||
std::stringstream str;
|
||||
|
||||
if(unit_recall_cost < 0) {
|
||||
unit_recall_cost = team_recall_cost;
|
||||
}
|
||||
|
||||
if(unit_recall_cost > team_recall_cost) {
|
||||
str << "<span color='#ff0000'>" << unit_recall_cost << "</span>";
|
||||
} else if(unit_recall_cost == team_recall_cost) {
|
||||
str << unit_recall_cost;
|
||||
} else if(unit_recall_cost < team_recall_cost) {
|
||||
str << "<span color='#00ff00'>" << unit_recall_cost << "</span>";
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string tstr_key(unit_const_ptr u, const t_string& (unit::* fcn)() const)
|
||||
{
|
||||
return (u.get()->*fcn)().str();
|
||||
}
|
||||
|
||||
static std::string trait_key(unit_const_ptr u)
|
||||
{
|
||||
return !u->trait_names().empty() ? u->trait_names().front().str() : "";
|
||||
}
|
||||
|
||||
template<typename Fnc>
|
||||
void tunit_recall::init_sorting_option(std::vector<tgenerator_::torder_func>& order_funcs, Fnc filter_on)
|
||||
{
|
||||
order_funcs[0] = [this, filter_on](unsigned i1, unsigned i2) {
|
||||
return filter_on((*recall_list_)[i1]) < filter_on((*recall_list_)[i2]);
|
||||
};
|
||||
|
||||
order_funcs[1] = [this, filter_on](unsigned i1, unsigned i2) {
|
||||
return filter_on((*recall_list_)[i1]) > filter_on((*recall_list_)[i2]);
|
||||
};
|
||||
}
|
||||
|
||||
static std::string get_title_suffix(int side_num)
|
||||
{
|
||||
if(!resources::teams || !resources::units) {
|
||||
return "";
|
||||
}
|
||||
|
||||
unit_map& units = *resources::units;
|
||||
|
||||
int controlled_recruiters = 0;
|
||||
for(const auto& team : *resources::teams) {
|
||||
if(team.is_local_human() && !team.recruits().empty() && units.find_leader(team.side()) !=units.end()) {
|
||||
++controlled_recruiters;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream msg;
|
||||
if(controlled_recruiters >= 2) {
|
||||
unit_map::const_iterator leader = resources::units->find_leader(side_num);
|
||||
if(leader != resources::units->end() && !leader->name().empty()) {
|
||||
msg << " (" << leader->name(); msg << ")";
|
||||
}
|
||||
}
|
||||
|
||||
return msg.str();
|
||||
}
|
||||
|
||||
void tunit_recall::pre_show(twindow& window)
|
||||
{
|
||||
tlabel& title = find_widget<tlabel>(&window, "title", true);
|
||||
title.set_label(title.label() + get_title_suffix(team_.side()));
|
||||
|
||||
ttext_box* filter
|
||||
= find_widget<ttext_box>(&window, "filter_box", false, true);
|
||||
|
||||
filter->set_text_changed_callback(
|
||||
std::bind(&tunit_recall::filter_text_changed, this, _1, _2));
|
||||
|
||||
window.keyboard_capture(filter);
|
||||
|
||||
tlistbox& list = find_widget<tlistbox>(&window, "recall_list", false);
|
||||
|
||||
#ifdef GUI2_EXPERIMENTAL_LISTBOX
|
||||
connect_signal_notify_modified(*list,
|
||||
std::bind(&tunit_recall::list_item_clicked,
|
||||
*this, std::ref(window)));
|
||||
#else
|
||||
list.set_callback_value_change(
|
||||
dialog_callback<tunit_recall, &tunit_recall::list_item_clicked>);
|
||||
#endif
|
||||
|
||||
list.clear();
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<tbutton>(&window, "dismiss", false),
|
||||
std::bind(&tunit_recall::dismiss_unit, this, std::ref(window)));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<tbutton>(&window, "show_help", false),
|
||||
std::bind(&tunit_recall::show_help, this, std::ref(window)));
|
||||
|
||||
for(const unit_const_ptr& unit : *recall_list_) {
|
||||
std::map<std::string, string_map> row_data;
|
||||
string_map column;
|
||||
|
||||
std::string mods
|
||||
= "~RC(" + unit->team_color() + ">" + team::get_side_color_index(unit->side()) + ")";
|
||||
|
||||
if(unit->can_recruit()) {
|
||||
mods += "~BLIT(" + unit::leader_crown() + ")";
|
||||
}
|
||||
|
||||
for(const std::string& overlay : unit->overlays()) {
|
||||
mods += "~BLIT(" + overlay + ")";
|
||||
}
|
||||
|
||||
column["label"] = unit->absolute_image() + mods;
|
||||
row_data.insert(std::make_pair("unit_image", column));
|
||||
|
||||
column["label"] = unit->type_name();
|
||||
row_data.insert(std::make_pair("unit_type", column));
|
||||
|
||||
column["label"] = format_cost_string(unit->recall_cost(), team_.recall_cost());
|
||||
column["use_markup"] = "true";
|
||||
row_data.insert(std::make_pair("unit_recall_cost", column));
|
||||
|
||||
const std::string& name = !unit->name().empty() ? unit->name().str() : utils::unicode_en_dash;
|
||||
column["label"] = name;
|
||||
row_data.insert(std::make_pair("unit_name", column));
|
||||
|
||||
column["label"] = format_level_string(unit->level());
|
||||
row_data.insert(std::make_pair("unit_level", column));
|
||||
|
||||
std::stringstream exp_str;
|
||||
exp_str << font::span_color(unit->xp_color()) << unit->experience() << "/"
|
||||
<< (unit->can_advance() ? std::to_string(unit->max_experience()) : utils::unicode_en_dash) << "</span>";
|
||||
|
||||
column["label"] = exp_str.str();
|
||||
row_data.insert(std::make_pair("unit_experience", column));
|
||||
|
||||
// Since the table widgets use heavy formatting, we save a bare copy
|
||||
// of certain options to filter on.
|
||||
std::string filter_text = unit->type_name() + " " + name + " " + std::to_string(unit->level());
|
||||
|
||||
std::string traits;
|
||||
for(const std::string& trait : unit->trait_names()) {
|
||||
traits += (traits.empty() ? "" : "\n") + trait;
|
||||
filter_text += " " + trait;
|
||||
}
|
||||
|
||||
column["label"] = !traits.empty() ? traits : utils::unicode_en_dash;
|
||||
row_data.insert(std::make_pair("unit_traits", column));
|
||||
|
||||
list.add_row(row_data);
|
||||
filter_options_.push_back(filter_text);
|
||||
}
|
||||
|
||||
std::vector<tgenerator_::torder_func> order_funcs(2);
|
||||
|
||||
init_sorting_option(order_funcs, std::bind(&tstr_key, _1, &unit::type_name));
|
||||
list.set_column_order(0, order_funcs);
|
||||
|
||||
init_sorting_option(order_funcs, std::bind(&tstr_key, _1, &unit::name));
|
||||
list.set_column_order(1, order_funcs);
|
||||
|
||||
init_sorting_option(order_funcs, std::bind(&unit::level, _1));
|
||||
list.set_column_order(2, order_funcs);
|
||||
|
||||
init_sorting_option(order_funcs, std::bind(&unit::experience, _1));
|
||||
list.set_column_order(3, order_funcs);
|
||||
|
||||
init_sorting_option(order_funcs, std::bind(&trait_key, _1));
|
||||
list.set_column_order(4, order_funcs);
|
||||
|
||||
list_item_clicked(window);
|
||||
}
|
||||
|
||||
void tunit_recall::dismiss_unit(twindow& window)
|
||||
{
|
||||
LOG_DP << "Recall list units:\n"; dump_recall_list_to_console(*recall_list_);
|
||||
|
||||
tlistbox& list = find_widget<tlistbox>(&window, "recall_list", false);
|
||||
const int index = list.get_selected_row();
|
||||
|
||||
const unit& u = *recall_list_->at(index);
|
||||
|
||||
// If the unit is of level > 1, or is close to advancing, we warn the player about it
|
||||
std::stringstream message;
|
||||
if(u.loyal()) {
|
||||
message << _("This unit is loyal and requires no upkeep.") << " " << (u.gender() == unit_race::MALE
|
||||
? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
|
||||
} else if(u.level() > 1) {
|
||||
message << _("This unit is an experienced one, having advanced levels.") << " " << (u.gender() == unit_race::MALE
|
||||
? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
|
||||
} else if(u.experience() > u.max_experience()/2) {
|
||||
message << _("This unit is close to advancing a level.") << " " << (u.gender() == unit_race::MALE
|
||||
? _("Do you really want to dismiss him?")
|
||||
: _("Do you really want to dismiss her?"));
|
||||
}
|
||||
|
||||
if(!message.str().empty()) {
|
||||
const int res = gui2::show_message(window.video(), _("Dismiss Unit"), message.str(), gui2::tmessage::yes_no_buttons);
|
||||
|
||||
if(res != gui2::twindow::OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*recall_list_->erase(recall_list_->begin() + index);
|
||||
|
||||
// Remove the entry from the dialog list
|
||||
list.remove_row(index);
|
||||
list_item_clicked(window);
|
||||
|
||||
// Remove the entry from the filter list
|
||||
filter_options_.erase(filter_options_.begin() + index);
|
||||
assert(filter_options_.size() == list.get_item_count());
|
||||
|
||||
LOG_DP << "Dismissing a unit, side = " << u.side() << ", id = '" << u.id() << "'\n";
|
||||
LOG_DP << "That side's recall list:\n";
|
||||
dump_recall_list_to_console(team_.recall_list());
|
||||
|
||||
// Find the unit in the recall list.
|
||||
unit_ptr dismissed_unit = team_.recall_list().find_if_matches_id(u.id());
|
||||
assert(dismissed_unit);
|
||||
|
||||
// Record the dismissal, then delete the unit.
|
||||
synced_context::run_and_throw("disband", replay_helper::get_disband(dismissed_unit->id()));
|
||||
|
||||
// Close the dialog if all units are dismissed
|
||||
if(list.get_item_count() == 0) {
|
||||
window.set_retval(twindow::CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
void tunit_recall::show_help(twindow& window)
|
||||
{
|
||||
help::show_help(window.video(), "recruit_and_recall");
|
||||
}
|
||||
|
||||
void tunit_recall::list_item_clicked(twindow& window)
|
||||
{
|
||||
const int selected_row
|
||||
= find_widget<tlistbox>(&window, "recall_list", false).get_selected_row();
|
||||
|
||||
if(selected_row == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
find_widget<tunit_preview_pane>(&window, "unit_details", false)
|
||||
.set_displayed_unit(recall_list_->at(selected_row).get());
|
||||
}
|
||||
|
||||
void tunit_recall::post_show(twindow& window)
|
||||
{
|
||||
if(get_retval() == twindow::OK) {
|
||||
selected_index_ = find_widget<tlistbox>(&window, "recall_list", false)
|
||||
.get_selected_row();
|
||||
}
|
||||
}
|
||||
|
||||
void tunit_recall::filter_text_changed(ttext_* textbox, const std::string& text)
|
||||
{
|
||||
twindow& window = *textbox->get_window();
|
||||
|
||||
tlistbox& list = find_widget<tlistbox>(&window, "recall_list", false);
|
||||
|
||||
const std::vector<std::string> words = utils::split(text, ' ');
|
||||
|
||||
if(words == last_words_)
|
||||
return;
|
||||
last_words_ = words;
|
||||
|
||||
std::vector<bool> show_items(list.get_item_count(), true);
|
||||
|
||||
if(!text.empty()) {
|
||||
for(unsigned int i = 0; i < list.get_item_count(); i++) {
|
||||
bool found = false;
|
||||
|
||||
for(const auto & word : words) {
|
||||
found = std::search(filter_options_[i].begin(),
|
||||
filter_options_[i].end(),
|
||||
word.begin(),
|
||||
word.end(),
|
||||
chars_equal_insensitive)
|
||||
!= filter_options_[i].end();
|
||||
|
||||
if(!found) {
|
||||
// one word doesn't match, we don't reach words.end()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
show_items[i] = found;
|
||||
}
|
||||
}
|
||||
|
||||
list.set_row_shown(show_items);
|
||||
}
|
||||
|
||||
}
|
78
src/gui/dialogs/unit_recall.hpp
Normal file
78
src/gui/dialogs/unit_recall.hpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (C) 2016 by 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_UNIT_RECALL_HPP_INCLUDED
|
||||
#define GUI_DIALOGS_UNIT_RECALL_HPP_INCLUDED
|
||||
|
||||
#include "gui/dialogs/dialog.hpp"
|
||||
#include "gui/widgets/group.hpp"
|
||||
#include "gui/widgets/generator.hpp"
|
||||
#include "units/race.hpp"
|
||||
#include "units/ptr.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class team;
|
||||
class unit_type;
|
||||
|
||||
namespace gui2
|
||||
{
|
||||
|
||||
class ttext_;
|
||||
|
||||
class tunit_recall : public tdialog
|
||||
{
|
||||
typedef std::shared_ptr<std::vector<unit_const_ptr> > recalls_ptr_vector;
|
||||
|
||||
public:
|
||||
tunit_recall(recalls_ptr_vector& recall_list, team& team);
|
||||
|
||||
int get_selected_index() const
|
||||
{
|
||||
return selected_index_;
|
||||
}
|
||||
|
||||
private:
|
||||
recalls_ptr_vector& recall_list_;
|
||||
|
||||
team& team_;
|
||||
|
||||
int selected_index_;
|
||||
|
||||
std::vector<std::string> filter_options_;
|
||||
std::vector<std::string> last_words_;
|
||||
|
||||
template<typename T>
|
||||
void init_sorting_option(std::vector<tgenerator_::torder_func>& order_funcs, T filter_on);
|
||||
|
||||
/** Callbacks */
|
||||
void list_item_clicked(twindow& window);
|
||||
void filter_text_changed(ttext_* textbox, const std::string& text);
|
||||
void dismiss_unit(twindow& window);
|
||||
void show_help(twindow& window);
|
||||
|
||||
/** Inherited from tdialog, implemented by REGISTER_DIALOG. */
|
||||
virtual const std::string& window_id() const;
|
||||
|
||||
/** Inherited from tdialog. */
|
||||
void pre_show(twindow& window);
|
||||
|
||||
/** Inherited from tdialog. */
|
||||
void post_show(twindow& window);
|
||||
};
|
||||
|
||||
} // namespace gui2
|
||||
|
||||
#endif /* ! GUI_DIALOGS_UNIT_RECALL_HPP_INCLUDED */
|
|
@ -25,13 +25,13 @@
|
|||
#include "gui/widgets/window.hpp"
|
||||
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "help/help.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "play_controller.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "team.hpp"
|
||||
#include "units/attack_type.hpp"
|
||||
#include "units/types.hpp"
|
||||
#include "units/unit.hpp"
|
||||
|
||||
|
@ -47,14 +47,15 @@ REGISTER_WIDGET(unit_preview_pane)
|
|||
void tunit_preview_pane::finalize_setup()
|
||||
{
|
||||
// Icons
|
||||
icon_type_ = find_widget<timage>(this, "type_image" , false, false);
|
||||
icon_race_ = find_widget<timage>(this, "type_race" , false, false);
|
||||
icon_alignment_ = find_widget<timage>(this, "type_alignment", false, false);
|
||||
icon_type_ = find_widget<timage>(this, "type_image" , false, false);
|
||||
icon_race_ = find_widget<timage>(this, "type_race" , false, false);
|
||||
icon_alignment_ = find_widget<timage>(this, "type_alignment", false, false);
|
||||
|
||||
// Labels
|
||||
label_name_ = find_widget<tlabel>(this, "type_name" , false, false);
|
||||
label_level_ = find_widget<tlabel>(this, "type_level" , false, false);
|
||||
label_details_ = find_widget<tlabel>(this, "type_details", false, false);
|
||||
label_name_ = find_widget<tlabel>(this, "type_name" , false, false);
|
||||
label_level_ = find_widget<tlabel>(this, "type_level" , false, false);
|
||||
label_details_ = find_widget<tlabel>(this, "type_details", false, false);
|
||||
label_details_minimal_ = find_widget<tlabel>(this, "type_details_minimal", false, false);
|
||||
|
||||
// Profile button
|
||||
button_profile_ = find_widget<tbutton>(this, "type_profile", false, false);
|
||||
|
@ -65,6 +66,33 @@ void tunit_preview_pane::finalize_setup()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Both unit and unit_type use the same format (vector of attack_types) for their
|
||||
* attack data, meaning we can keep this as a helper function.
|
||||
*/
|
||||
void tunit_preview_pane::print_attack_details(const std::vector<attack_type>& attacks, std::stringstream& str)
|
||||
{
|
||||
str << "<b>" << _("Attacks") << "</b>" << "\n";
|
||||
|
||||
for(const auto& a : attacks) {
|
||||
str << "<span color='#f5e6c1'>" << a.damage()
|
||||
<< font::weapon_numbers_sep << a.num_attacks() << " " << a.name() << "</span>" << "\n";
|
||||
|
||||
str << "<span color='#a69275'>" << " " << a.range()
|
||||
<< font::weapon_details_sep << a.type() << "</span>" << "\n";
|
||||
|
||||
const std::string special = a.weapon_specials();
|
||||
if (!special.empty()) {
|
||||
str << "<span color='#a69275'>" << " " << special << "</span>" << "\n";
|
||||
}
|
||||
|
||||
const std::string accuracy_parry = a.accuracy_parry_description();
|
||||
if(!accuracy_parry.empty()) {
|
||||
str << "<span color='#a69275'>" << " " << accuracy_parry << "</span>" << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tunit_preview_pane::set_displayed_type(const unit_type* type)
|
||||
{
|
||||
// Sets the current type id for the profile button callback to use
|
||||
|
@ -122,14 +150,11 @@ void tunit_preview_pane::set_displayed_type(const unit_type* type)
|
|||
str << "<b>" << _("MP: ") << "</b>"
|
||||
<< type->movement() << "\n";
|
||||
|
||||
str << " \n";
|
||||
str << "\n";
|
||||
|
||||
// Print trait details
|
||||
bool has_traits = false;
|
||||
std::stringstream t_str;
|
||||
|
||||
for(const auto& tr : type->possible_traits())
|
||||
{
|
||||
for(const auto& tr : type->possible_traits()) {
|
||||
if(tr["availability"] != "musthave") continue;
|
||||
|
||||
const std::string gender_string =
|
||||
|
@ -143,50 +168,28 @@ void tunit_preview_pane::set_displayed_type(const unit_type* type)
|
|||
if(!name.empty()) {
|
||||
t_str << " " << name << "\n";
|
||||
}
|
||||
|
||||
has_traits = true;
|
||||
}
|
||||
|
||||
if(has_traits) {
|
||||
if(!t_str.str().empty()) {
|
||||
str << "<b>" << _("Traits") << "</b>" << "\n";
|
||||
str << t_str.str();
|
||||
str << " \n";
|
||||
str << "\n";
|
||||
}
|
||||
|
||||
// Print ability details
|
||||
if(!type->abilities().empty()) {
|
||||
str << "<b>" << _("Abilities") << "</b>" << "\n";
|
||||
|
||||
for(const auto& ab : type->abilities())
|
||||
{
|
||||
for(const auto& ab : type->abilities()) {
|
||||
str << " " << ab << "\n";
|
||||
}
|
||||
|
||||
str << " \n";
|
||||
str << "\n";
|
||||
}
|
||||
|
||||
// Print attack details
|
||||
if(!type->attacks().empty()) {
|
||||
str << "<b>" << _("Attacks") << "</b>" << "\n";
|
||||
|
||||
for(const auto& a : type->attacks())
|
||||
{
|
||||
str << "<span color='#f5e6c1'>" << a.damage()
|
||||
<< font::weapon_numbers_sep << a.num_attacks() << " " << a.name() << "</span>" << "\n";
|
||||
|
||||
str << "<span color='#a69275'>" << " " << a.range()
|
||||
<< font::weapon_details_sep << a.type() << "</span>" << "\n";
|
||||
|
||||
const std::string special = a.weapon_specials();
|
||||
if (!special.empty()) {
|
||||
str << "<span color='#a69275'>" << " " << special << "</span>" << "\n";
|
||||
}
|
||||
|
||||
const std::string accuracy_parry = a.accuracy_parry_description();
|
||||
if(!accuracy_parry.empty()) {
|
||||
str << "<span color='#a69275'>" << " " << accuracy_parry << "</span>" << "\n";
|
||||
}
|
||||
}
|
||||
print_attack_details(type->attacks(), str);
|
||||
}
|
||||
|
||||
label_details_->set_label(str.str());
|
||||
|
@ -217,7 +220,14 @@ void tunit_preview_pane::set_displayed_unit(const unit* unit)
|
|||
}
|
||||
|
||||
if(label_name_) {
|
||||
label_name_->set_label("<big>" + unit->type_name() + "</big>");
|
||||
std::string name;
|
||||
if(!unit->name().empty()) {
|
||||
name = "<span size='large'>" + unit->name() + "</span>" + "\n" + "<small><span color='#a69275'>" + unit->type_name() + "</span></small>";
|
||||
} else {
|
||||
name = "<span size='large'>" + unit->type_name() + "</span>\n";
|
||||
}
|
||||
|
||||
label_name_->set_label(name);
|
||||
label_name_->set_use_markup(true);
|
||||
}
|
||||
|
||||
|
@ -245,31 +255,19 @@ void tunit_preview_pane::set_displayed_unit(const unit* unit)
|
|||
unit->gender()));
|
||||
}
|
||||
|
||||
// For this, we want to display certain info in the details label if the corresponding
|
||||
// widgets aren't present in the definiton.
|
||||
if(label_details_) {
|
||||
if(label_details_minimal_) {
|
||||
std::stringstream str;
|
||||
str << "<small>";
|
||||
|
||||
if(!label_name_) {
|
||||
const std::string name = "<span size='large'>" + (!unit->name().empty() ? unit->name() : " ") + "</span>";
|
||||
str << name << "\n";
|
||||
}
|
||||
const std::string name = "<span size='large'>" + (!unit->name().empty() ? unit->name() : " ") + "</span>";
|
||||
str << name << "\n";
|
||||
|
||||
if(!icon_type_) {
|
||||
str << "<span color='#f5e6c1'>" << unit->type_name() << "</span>" << "\n";
|
||||
}
|
||||
str << "<span color='#f5e6c1'>" << unit->type_name() << "</span>" << "\n";
|
||||
|
||||
if(!label_level_) {
|
||||
str << "Lvl " << unit->level() << "\n";
|
||||
}
|
||||
str << "Lvl " << unit->level() << "\n";
|
||||
|
||||
if(!icon_alignment_) {
|
||||
str << unit->alignment() << "\n";
|
||||
}
|
||||
str << unit->alignment() << "\n";
|
||||
|
||||
std::string traits;
|
||||
|
||||
for(const std::string& trait : unit->trait_names()) {
|
||||
traits += (traits.empty() ? "" : ", ") + trait;
|
||||
}
|
||||
|
@ -286,14 +284,50 @@ void tunit_preview_pane::set_displayed_unit(const unit* unit)
|
|||
str << font::span_color(unit->xp_color())
|
||||
<< _("XP: ") << unit->experience() << "/" << unit->max_experience() << "</span>";
|
||||
|
||||
// TODO: enable
|
||||
//str << "\n"
|
||||
// << _("MP: ") << unit->movement_left() << "/" << unit->total_movement();
|
||||
label_details_minimal_->set_label(str.str());
|
||||
label_details_minimal_->set_use_markup(true);
|
||||
}
|
||||
|
||||
if(label_details_) {
|
||||
std::stringstream str;
|
||||
str << "<small>";
|
||||
|
||||
str << "<b>" << _("HP: ") << "</b>"
|
||||
<<font::span_color(unit->hp_color()) << unit->hitpoints() << "/" << unit->max_hitpoints() << "</span>" << " | ";
|
||||
|
||||
str << "<b>" << _("XP: ") << "</b>"
|
||||
<< font::span_color(unit->xp_color()) << unit->experience() << "/" << unit->max_experience() << "</span>" << " | ";
|
||||
|
||||
str << "<b>" << _("MP: ") << "</b>"
|
||||
<< unit->movement_left() << "/" << unit->total_movement();
|
||||
|
||||
str << "</small>";
|
||||
str << "\n\n";
|
||||
|
||||
// TODO: add abilty and attack printouts. Currently the only usecase of a unit display
|
||||
// (the attack dialog) doesn't need these.
|
||||
// Print trait details
|
||||
if(!unit->trait_names().empty()) {
|
||||
str << "<b>" << _("Traits") << "</b>" << "\n";
|
||||
|
||||
for(const auto& trait : unit->trait_names()) {
|
||||
str << " " << trait << "\n";
|
||||
}
|
||||
|
||||
str << "\n";
|
||||
}
|
||||
|
||||
if(!unit->get_ability_list().empty()) {
|
||||
str << "<b>" << _("Abilities") << "</b>" << "\n";
|
||||
|
||||
for(const auto& ab : unit->get_ability_list()) {
|
||||
str << " " << ab << "\n";
|
||||
}
|
||||
|
||||
str << "\n";
|
||||
}
|
||||
|
||||
if(!unit->attacks().empty()) {
|
||||
print_attack_details(unit->attacks(), str);
|
||||
}
|
||||
|
||||
label_details_->set_label(str.str());
|
||||
label_details_->set_use_markup(true);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class attack_type;
|
||||
class unit;
|
||||
class unit_type;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public:
|
|||
, label_name_(nullptr)
|
||||
, label_level_(nullptr)
|
||||
, label_details_(nullptr)
|
||||
, label_details_minimal_(nullptr)
|
||||
, button_profile_(nullptr)
|
||||
, image_mods_()
|
||||
{
|
||||
|
@ -86,18 +88,21 @@ protected:
|
|||
private:
|
||||
std::string current_type_;
|
||||
|
||||
timage* icon_type_;
|
||||
timage* icon_race_;
|
||||
timage* icon_alignment_;
|
||||
timage* icon_type_;
|
||||
timage* icon_race_;
|
||||
timage* icon_alignment_;
|
||||
|
||||
tlabel* label_name_;
|
||||
tlabel* label_level_;
|
||||
tlabel* label_details_;
|
||||
tlabel* label_name_;
|
||||
tlabel* label_level_;
|
||||
tlabel* label_details_;
|
||||
tlabel* label_details_minimal_;
|
||||
|
||||
tbutton* button_profile_;
|
||||
|
||||
std::string image_mods_;
|
||||
|
||||
void print_attack_details(const std::vector<attack_type>& attacks, std::stringstream& str);
|
||||
|
||||
enum tstate {
|
||||
ENABLED
|
||||
};
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "gui/dialogs/simple_item_selector.hpp"
|
||||
#include "gui/dialogs/edit_text.hpp"
|
||||
#include "gui/dialogs/unit_create.hpp"
|
||||
#include "gui/dialogs/unit_recall.hpp"
|
||||
#include "gui/dialogs/unit_recruit.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
|
@ -640,16 +641,22 @@ void menu_handler::recall(int side_num, const map_location &last_hex)
|
|||
return;
|
||||
}
|
||||
|
||||
int res = dialogs::recall_dialog(*gui_, recall_list_team, side_num, get_title_suffix(side_num), current_team.recall_cost());
|
||||
int unit_cost = current_team.recall_cost();
|
||||
if (res < 0) {
|
||||
gui2::tunit_recall dlg(recall_list_team, current_team);
|
||||
|
||||
dlg.show(gui_->video());
|
||||
|
||||
if(dlg.get_retval() != gui2::twindow::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
int res = dlg.get_selected_index();
|
||||
int unit_cost = current_team.recall_cost();
|
||||
|
||||
// we need to check if unit has a specific recall cost
|
||||
// if it does we use it elsewise we use the team.recall_cost()
|
||||
// the magic number -1 is what it gets set to if the unit doesn't
|
||||
// have a special recall_cost of its own.
|
||||
else if(recall_list_team->at(res)->recall_cost() > -1) {
|
||||
if(recall_list_team->at(res)->recall_cost() > -1) {
|
||||
unit_cost = recall_list_team->at(res)->recall_cost();
|
||||
}
|
||||
|
||||
|
@ -686,8 +693,7 @@ void menu_handler::recall(int side_num, const map_location &last_hex)
|
|||
true,
|
||||
synced_context::ignore_error_function);
|
||||
|
||||
if(!success)
|
||||
{
|
||||
if(!success) {
|
||||
ERR_NG << "menu_handler::recall(): Unit does not exist in the recall list." << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue