Made Attack dialog use a unit_preview_pane widget
This also adds the necessary changes to said widget to allow single-unit stats display. It still needs to be expanded somewhat. Right now it contains the minimum required for the attack dialog.
This commit is contained in:
parent
4889fd7534
commit
639548a108
6 changed files with 337 additions and 105 deletions
|
@ -1930,6 +1930,11 @@
|
|||
max="1"
|
||||
super="gui/window/resolution/grid"
|
||||
[/tag]
|
||||
[key]
|
||||
name="image_facing"
|
||||
type="string"
|
||||
default="right"
|
||||
[/key]
|
||||
[/tag]
|
||||
[tag]
|
||||
name="vertical_scrollbar"
|
||||
|
|
|
@ -254,6 +254,150 @@
|
|||
[/grid]
|
||||
#enddef
|
||||
|
||||
#define _GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_LEFT
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "center"
|
||||
vertical_alignment = "center"
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "type_image"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_alignment = "right"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "right"
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "type_details"
|
||||
definition = "default"
|
||||
|
||||
text_alignment = "right"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "right"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[button]
|
||||
id = "type_profile"
|
||||
definition = "default"
|
||||
|
||||
label = _ "Profile"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
#enddef
|
||||
|
||||
#define _GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_RIGHT
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "left"
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "type_details"
|
||||
definition = "default"
|
||||
|
||||
text_alignment = "left"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "left"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[button]
|
||||
id = "type_profile"
|
||||
definition = "default"
|
||||
|
||||
label = _ "Profile"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
horizontal_alignment = "center"
|
||||
vertical_alignment = "center"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "type_image"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
#enddef
|
||||
|
||||
#define _GUI_RESOLUTION DEFINITION_GRID
|
||||
[resolution]
|
||||
|
||||
|
@ -301,6 +445,22 @@
|
|||
{_GUI_RESOLUTION ({_GUI_UNIT_PREVIEW_PANE_MINIMAL})}
|
||||
[/unit_preview_pane_definition]
|
||||
|
||||
[unit_preview_pane_definition]
|
||||
id = "unit_minimal_left"
|
||||
description = "A more text-based unit preview pane, used in the attack dialog with the sprite to the left."
|
||||
|
||||
{_GUI_RESOLUTION ({_GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_LEFT})}
|
||||
[/unit_preview_pane_definition]
|
||||
|
||||
[unit_preview_pane_definition]
|
||||
id = "unit_minimal_right"
|
||||
description = "A more text-based unit preview pane, used in the attack dialog with the sprite to the right."
|
||||
|
||||
{_GUI_RESOLUTION ({_GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_RIGHT})}
|
||||
[/unit_preview_pane_definition]
|
||||
|
||||
#undef _GUI_UNIT_PREVIEW_PANE_FULL
|
||||
#undef _GUI_UNIT_PREVIEW_PANE_MINIMAL
|
||||
#undef _GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_LEFT
|
||||
#undef _GUI_UNIT_PREVIEW_PANE_UNIT_MINIMAL_RIGHT
|
||||
#undef _GUI_RESOLUTION
|
||||
|
|
|
@ -159,7 +159,13 @@
|
|||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = "true"
|
||||
{_GUI_BIG_ATTACKER_PANEL}
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[unit_preview_pane]
|
||||
id = "attacker_pane"
|
||||
definition = "unit_minimal_left"
|
||||
[/unit_preview_pane]
|
||||
[/column]
|
||||
|
||||
{GUI_VERTICAL_SPACER_LINE}
|
||||
|
@ -167,7 +173,14 @@
|
|||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = "true"
|
||||
{_GUI_BIG_DEFENDER_PANEL}
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[unit_preview_pane]
|
||||
id = "defender_pane"
|
||||
definition = "unit_minimal_right"
|
||||
image_facing = "left"
|
||||
[/unit_preview_pane]
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "gui/widgets/listbox.hpp"
|
||||
#endif
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "gui/widgets/unit_preview_pane.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "gettext.hpp"
|
||||
|
@ -94,82 +95,6 @@ set_label(twindow& window, const std::string& id, const std::string& label)
|
|||
}
|
||||
}
|
||||
|
||||
static std::string format_stats(const unit& u)
|
||||
{
|
||||
const std::string name = "<span size='large'>" + (!u.name().empty() ? u.name() : " ") + "</span>";
|
||||
std::string traits;
|
||||
|
||||
for(const std::string& trait : u.trait_names()) {
|
||||
traits += (traits.empty() ? "" : ", ") + trait;
|
||||
}
|
||||
|
||||
if (traits.empty()) {
|
||||
traits = " ";
|
||||
}
|
||||
|
||||
std::stringstream str;
|
||||
|
||||
str << name << "\n";
|
||||
|
||||
str << "<small>";
|
||||
|
||||
str << "<span color='#f5e6c1'>" << u.type_name() << "</span>" << "\n";
|
||||
|
||||
str << "Lvl " << u.level() << "\n";
|
||||
|
||||
str << u.alignment() << "\n";
|
||||
|
||||
str << traits << "\n";
|
||||
|
||||
str << font::span_color(u.hp_color())
|
||||
<< _("HP: ") << u.hitpoints() << "/" << u.max_hitpoints() << "</span>" << "\n";
|
||||
str << font::span_color(u.xp_color())
|
||||
<< _("XP: ") << u.experience() << "/" << u.max_experience() << "</span>";
|
||||
|
||||
str << "</small>";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
static std::string get_image_mods(const unit& u)
|
||||
{
|
||||
std::string res
|
||||
= "~RC(" + u.team_color() + ">" + team::get_side_color_index(u.side()) + ")";
|
||||
|
||||
if (u.can_recruit()) {
|
||||
res += "~BLIT(" + unit::leader_crown() + ")";
|
||||
}
|
||||
|
||||
for(const std::string& overlay : u.overlays()) {
|
||||
res += "~BLIT(" + overlay + ")";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void set_attacker_info(twindow& window, const unit& u)
|
||||
{
|
||||
set_label<timage>(window, "attacker_image", u.absolute_image() + get_image_mods(u));
|
||||
|
||||
tcontrol& attacker_name =
|
||||
find_widget<tcontrol>(&window, "attacker_stats", false);
|
||||
|
||||
attacker_name.set_use_markup(true);
|
||||
attacker_name.set_label(format_stats(u));
|
||||
}
|
||||
|
||||
static void set_defender_info(twindow& window, const unit& u)
|
||||
{
|
||||
// Ensure the defender image is always facing left
|
||||
set_label<timage>(window, "defender_image", u.absolute_image() + "~FL(horiz)" + get_image_mods(u));
|
||||
|
||||
tcontrol& defender_name =
|
||||
find_widget<tcontrol>(&window, "defender_stats", false);
|
||||
|
||||
defender_name.set_use_markup(true);
|
||||
defender_name.set_label(format_stats(u));
|
||||
}
|
||||
|
||||
static void set_weapon_info(twindow& window,
|
||||
const std::vector<battle_context>& weapons,
|
||||
const int best_weapon)
|
||||
|
@ -265,22 +190,15 @@ void tunit_attack::damage_calc_callback(twindow& window)
|
|||
|
||||
void tunit_attack::pre_show(twindow& window)
|
||||
{
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<tbutton>(&window, "attacker_profile", false),
|
||||
std::bind(&tunit_attack::profile_button_callback, this, std::ref(window),
|
||||
(*attacker_itor_).type_id()));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<tbutton>(&window, "defender_profile", false),
|
||||
std::bind(&tunit_attack::profile_button_callback, this, std::ref(window),
|
||||
(*defender_itor_).type_id()));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<tbutton>(&window, "damage_calculation", false),
|
||||
std::bind(&tunit_attack::damage_calc_callback, this, std::ref(window)));
|
||||
|
||||
set_attacker_info(window, *attacker_itor_);
|
||||
set_defender_info(window, *defender_itor_);
|
||||
find_widget<tunit_preview_pane>(&window, "attacker_pane", false)
|
||||
.set_displayed_unit(&(*attacker_itor_));
|
||||
|
||||
find_widget<tunit_preview_pane>(&window, "defender_pane", false)
|
||||
.set_displayed_unit(&(*defender_itor_));
|
||||
|
||||
selected_weapon_ = -1;
|
||||
set_weapon_info(window, weapons_, best_weapon_);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "resources.hpp"
|
||||
#include "team.hpp"
|
||||
#include "units/types.hpp"
|
||||
#include "units/unit.hpp"
|
||||
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
|
@ -193,6 +194,115 @@ void tunit_preview_pane::set_displayed_type(const unit_type* type)
|
|||
}
|
||||
}
|
||||
|
||||
void tunit_preview_pane::set_displayed_unit(const unit* unit)
|
||||
{
|
||||
// Sets the current type id for the profile button callback to use
|
||||
current_type_ = unit->type_id();
|
||||
|
||||
if(icon_type_) {
|
||||
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 + ")";
|
||||
}
|
||||
|
||||
// We assume sprites are always drawn facing right
|
||||
if(image_facing_ == "left") {
|
||||
mods += "~FL(horiz)";
|
||||
}
|
||||
|
||||
icon_type_->set_label(unit->absolute_image() + mods);
|
||||
}
|
||||
|
||||
if(label_name_) {
|
||||
label_name_->set_label("<big>" + unit->type_name() + "</big>");
|
||||
label_name_->set_use_markup(true);
|
||||
}
|
||||
|
||||
if(label_level_) {
|
||||
utils::string_map symbols;
|
||||
symbols["lvl"] = std::to_string(unit->level());
|
||||
|
||||
std::string l_str = vgettext("Lvl $lvl", symbols);
|
||||
|
||||
label_level_->set_label("<b>" + l_str + "</b>");
|
||||
label_level_->set_use_markup(true);
|
||||
}
|
||||
|
||||
if(icon_race_) {
|
||||
icon_race_->set_label("icons/unit-groups/race_" + unit->race()->id() + "_30.png");
|
||||
icon_race_->set_tooltip(unit->race()->name(unit->gender()));
|
||||
}
|
||||
|
||||
if(icon_alignment_) {
|
||||
const std::string& alignment_name = unit->alignment().to_string();
|
||||
|
||||
icon_alignment_->set_label("icons/alignments/alignment_" + alignment_name + "_30.png");
|
||||
icon_alignment_->set_tooltip(unit_type::alignment_description(
|
||||
unit->alignment(),
|
||||
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_) {
|
||||
std::stringstream str;
|
||||
str << "<small>";
|
||||
|
||||
if(!label_name_) {
|
||||
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";
|
||||
}
|
||||
|
||||
if(!label_level_) {
|
||||
str << "Lvl " << unit->level() << "\n";
|
||||
}
|
||||
|
||||
if(!icon_alignment_) {
|
||||
str << unit->alignment() << "\n";
|
||||
}
|
||||
|
||||
std::string traits;
|
||||
|
||||
for(const std::string& trait : unit->trait_names()) {
|
||||
traits += (traits.empty() ? "" : ", ") + trait;
|
||||
}
|
||||
|
||||
if(traits.empty()) {
|
||||
traits = " ";
|
||||
}
|
||||
|
||||
str << traits << "\n";
|
||||
|
||||
str << font::span_color(unit->hp_color())
|
||||
<< _("HP: ") << unit->hitpoints() << "/" << unit->max_hitpoints() << "</span>" << "\n";
|
||||
|
||||
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();
|
||||
|
||||
str << "</small>";
|
||||
|
||||
// TODO: add abilty and attack printouts. Currently the only usecase of a unit display
|
||||
// (the attack dialog) doesn't need these.
|
||||
|
||||
label_details_->set_label(str.str());
|
||||
label_details_->set_use_markup(true);
|
||||
}
|
||||
}
|
||||
|
||||
void tunit_preview_pane::profile_button_callback()
|
||||
{
|
||||
if(get_window()) {
|
||||
|
@ -200,6 +310,15 @@ void tunit_preview_pane::profile_button_callback()
|
|||
}
|
||||
}
|
||||
|
||||
void tunit_preview_pane::set_image_facing(const std::string& facing)
|
||||
{
|
||||
if(facing != "left" && facing != "right") {
|
||||
return;
|
||||
}
|
||||
|
||||
image_facing_ = facing;
|
||||
}
|
||||
|
||||
void tunit_preview_pane::set_active(const bool /*active*/)
|
||||
{
|
||||
/* DO NOTHING */
|
||||
|
@ -255,6 +374,7 @@ namespace implementation
|
|||
|
||||
tbuilder_unit_preview_pane::tbuilder_unit_preview_pane(const config& cfg)
|
||||
: tbuilder_control(cfg)
|
||||
, image_facing_(cfg["image_facing"])
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -275,6 +395,7 @@ twidget* tbuilder_unit_preview_pane::build() const
|
|||
|
||||
widget->init_grid(conf->grid);
|
||||
widget->finalize_setup();
|
||||
widget->set_image_facing(image_facing_);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class unit;
|
||||
class unit_type;
|
||||
|
||||
namespace gui2
|
||||
|
@ -40,28 +41,28 @@ class tunit_preview_pane : public tcontainer_
|
|||
|
||||
public:
|
||||
tunit_preview_pane()
|
||||
: tcontainer_(1)
|
||||
: tcontainer_(1)
|
||||
, current_type_("")
|
||||
, icon_type_()
|
||||
, icon_race_()
|
||||
, icon_alignment_()
|
||||
, label_name_()
|
||||
, label_level_()
|
||||
, label_details_()
|
||||
, button_profile_()
|
||||
, icon_type_(nullptr)
|
||||
, icon_race_(nullptr)
|
||||
, icon_alignment_(nullptr)
|
||||
, label_name_(nullptr)
|
||||
, label_level_(nullptr)
|
||||
, label_details_(nullptr)
|
||||
, button_profile_(nullptr)
|
||||
, image_facing_("right")
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the interneral sub-widget pointers.
|
||||
* Should be called when building the window, so the pointers
|
||||
* are initilized when set_displayed_type() is called.
|
||||
*/
|
||||
void finalize_setup();
|
||||
|
||||
/** Displays the stats of a specified unit type */
|
||||
void set_displayed_type(const unit_type* type);
|
||||
|
||||
/** Displays the stats of a specific unit */
|
||||
void set_displayed_unit(const unit* unit);
|
||||
|
||||
/** Sets the facing of the unit image */
|
||||
void set_image_facing(const std::string& facing);
|
||||
|
||||
/** Callback for the profile button */
|
||||
void profile_button_callback();
|
||||
|
||||
|
@ -74,6 +75,14 @@ public:
|
|||
/** See @ref tcontrol::get_state. */
|
||||
virtual unsigned get_state() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initializes the interneral sub-widget pointers.
|
||||
* Should be called when building the window, so the pointers
|
||||
* are initilized when set_displayed_type() is called.
|
||||
*/
|
||||
void finalize_setup();
|
||||
|
||||
private:
|
||||
std::string current_type_;
|
||||
|
||||
|
@ -87,6 +96,8 @@ private:
|
|||
|
||||
tbutton* button_profile_;
|
||||
|
||||
std::string image_facing_;
|
||||
|
||||
enum tstate {
|
||||
ENABLED
|
||||
};
|
||||
|
@ -121,11 +132,15 @@ namespace implementation
|
|||
|
||||
struct tbuilder_unit_preview_pane : public tbuilder_control
|
||||
{
|
||||
public:
|
||||
explicit tbuilder_unit_preview_pane(const config& cfg);
|
||||
|
||||
using tbuilder_control::build;
|
||||
|
||||
twidget* build() const;
|
||||
|
||||
private:
|
||||
std::string image_facing_;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
|
|
Loading…
Add table
Reference in a new issue