Added a new attack dialog.

This initial version is just a small proof of concept thing, its main
goal is to write a new chapter in the design documentation. The dialog
is available when started with --new-widgets.
This commit is contained in:
Mark de Wever 2010-04-24 20:39:25 +00:00
parent ec5c9ca846
commit 429b2b6d86
9 changed files with 545 additions and 0 deletions

View file

@ -37,6 +37,7 @@ Version 1.9.0-svn:
* Fixed bug #15727: Allow wml message titles to wrap
screen
* Added the total number of villages to the status table lists
* Added a new attack dialog, available for testing with --new-widgets
* WML Engine:
* Deprecated [set_variable]'s random key, use rand instead
* Renamed [unit][status] healable to unhealable so it can default to 'no'

View file

@ -0,0 +1,293 @@
#textdomain wesnoth-lib
###
### Definition of the window select which unit to attack
###
#define _GUI_BIG_ATTACKER_PANEL
[grid]
id = "attacker"
linked_group = "unit"
[row]
[column]
border = "all"
border_size = 5
[image]
id = "attacker_portrait"
[/image]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "attacker_name"
definition = "alignment"
[/label]
[/column]
[/row]
[/grid]
#enddef
#define _GUI_BIG_DEFENDER_PANEL
[grid]
id = "defender"
linked_group = "unit"
[row]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "defender_name"
definition = "alignment"
text_alignment = "right"
[/label]
[/column]
[column]
border = "all"
border_size = 5
[image]
id = "defender_portrait"
[/image]
[/column]
[/row]
[/grid]
#enddef
#define _GUI_BIG_UNIT_PANEL
[grid]
[row]
[column]
{_GUI_BIG_ATTACKER_PANEL}
[/column]
[column]
{_GUI_BIG_DEFENDER_PANEL}
[/column]
[/row]
[/grid]
#enddef
#define _GUI_BIG_WEAPON_PANEL
[grid]
[row]
[column]
horizontal_grow = "true"
[listbox]
id = "weapon_list"
definition = "default"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
return_value_id = "ok"
[grid]
[row]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "attacker_weapon"
definition = "alignment"
linked_group = "weapon"
[/label]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "defender_weapon"
definition = "alignment"
linked_group = "weapon"
text_alignment = "right"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
[/row]
[/grid]
#enddef
#define _GUI_BUTTON_ROW
[grid]
[row]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "ok"
definition = "default"
label = _ "Attack"
[/button]
[/column]
[column]
border = "all"
border_size = 5
[button]
id = "cancel"
definition = "default"
label = _ "Cancel"
[/button]
[/column]
[/row]
[/grid]
#enddef
[window]
id = "unit_attack"
description = "Unit attack dialog."
[resolution]
definition = "default"
automatic_placement = "true"
vertical_placement = "center"
horizontal_placement = "center"
# Both unit panels are the same width.
[linked_group]
id = "unit"
fixed_width = "true"
[/linked_group]
# All weapons share the same size, regardless whether attacker or
# defender.
[linked_group]
id = "weapon"
fixed_width = "true"
[/linked_group]
[grid]
[row]
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
definition = "title"
label = _ "Attack enemy"
[/label]
[/column]
[/row]
[row]
[column]
horizontal_grow = "true"
{_GUI_BIG_UNIT_PANEL}
[/column]
[/row]
[row]
[column]
horizontal_grow = "true"
{_GUI_BIG_WEAPON_PANEL}
[/column]
[/row]
[row]
[column]
horizontal_grow = "true"
{_GUI_BUTTON_ROW}
[/column]
[/row]
[/grid]
[/resolution]
[/window]

View file

@ -74,6 +74,7 @@ src/gui/dialogs/mp_create_game.cpp
src/gui/dialogs/mp_method_selection.cpp
src/gui/dialogs/title_screen.cpp
src/gui/dialogs/transient_message.cpp
src/gui/dialogs/unit_attack.cpp
src/gui/dialogs/unit_create.cpp
src/gui/dialogs/wml_message.cpp
src/gui/widgets/button.cpp

View file

@ -349,6 +349,7 @@ set(wesnoth-main_SRC
gui/dialogs/mp_cmd_wrapper.cpp
gui/dialogs/title_screen.cpp
gui/dialogs/transient_message.cpp
gui/dialogs/unit_attack.cpp
gui/dialogs/unit_create.cpp
gui/dialogs/wml_message.cpp
gui/widgets/button.cpp

View file

@ -175,6 +175,7 @@ wesnoth_source = \
gui/dialogs/mp_cmd_wrapper.cpp \
gui/dialogs/title_screen.cpp \
gui/dialogs/transient_message.cpp \
gui/dialogs/unit_attack.cpp \
gui/dialogs/unit_create.cpp \
gui/dialogs/wml_message.cpp \
gui/widgets/button.cpp \

View file

@ -334,6 +334,7 @@ wesnoth_sources = Split("""
gui/dialogs/mp_cmd_wrapper.cpp
gui/dialogs/title_screen.cpp
gui/dialogs/transient_message.cpp
gui/dialogs/unit_attack.cpp
gui/dialogs/unit_create.cpp
gui/dialogs/wml_message.cpp
gui/dialogs/icon_message.cpp

View file

@ -0,0 +1,152 @@
/* $Id$ */
/*
Copyright (C) 2010 by Mark de Wever <koraq@xs4all.nl>
Part of 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 version 2
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_attack.hpp"
#include "gui/widgets/image.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "unit.hpp"
namespace gui2 {
/*WIKI
* @page = GUIWindowDefinitionWML
* @order = 2_unit_attack
*
* == Unit attack ==
*
* This shows the dialog for attacking units.
*
* @start_table = grid
*
* attacker_portrait (image) Shows the portrait of the attacking unit.
* attacker_icon (image) Shows the icon of the attacking unit.
* attacker_name (control) Shows the name of the attacking unit.
*
*
* defender_portrait (image) Shows the portrait of the defending unit.
* defender_icon (image) Shows the icon of the defending unit.
* defender_name (control) Shows the name of the defending unit.
*
*
* (weapon_list) (listbox) The list with weapons to choos from.
* -[attacker_weapon] (control) The weapon for the attacker to use.
* -[defender_weapon] (control) The weapon for the defender to use.
*
* @end_table
*/
REGISTER_WINDOW(unit_attack)
tunit_attack::tunit_attack(
const unit_map::iterator& attacker_itor
, const unit_map::iterator& defender_itor
, const std::vector<battle_context>& weapons
, const int best_weapon)
: selected_weapon_(-1)
, attacker_itor_(attacker_itor)
, defender_itor_(defender_itor)
, weapons_(weapons)
, best_weapon_(best_weapon)
{
}
template<class T>
static void set_label(
twindow& window
, const std::string& id
, const std::string& label)
{
T* widget = find_widget<T>(&window, id, false, false);
if(widget) {
widget->set_label(label);
}
}
static void set_attacker_info(twindow& w, unit& u)
{
set_label<timage>(w, "attacker_portrait", u.absolute_image());
set_label<timage>(w, "attacker_icon", u.absolute_image());
set_label<tcontrol>(w, "attacker_name", u.name());
}
static void set_defender_info(twindow& w, unit& u)
{
set_label<timage>(w, "defender_portrait", u.absolute_image());
set_label<timage>(w, "defender_icon", u.absolute_image());
set_label<tcontrol>(w, "defender_name", u.name());
}
static void set_weapon_info(twindow& window
, const std::vector<battle_context>& weapons
, const int best_weapon)
{
tlistbox& weapon_list =
find_widget<tlistbox>(&window, "weapon_list", false);
window.keyboard_capture(&weapon_list);
const config empty;
attack_type no_weapon(empty);
for (size_t i = 0; i < weapons.size(); ++i) {
const battle_context::unit_stats& attacker =
weapons[i].get_attacker_stats();
const battle_context::unit_stats& defender =
weapons[i].get_defender_stats();
const attack_type& attacker_weapon = attack_type(*attacker.weapon);
const attack_type& defender_weapon = attack_type(
defender.weapon ? *defender.weapon : no_weapon);
std::map<std::string, string_map> data;
string_map item;
item["label"] = attacker_weapon.name();
data.insert(std::make_pair("attacker_weapon", item));
item["label"] = defender_weapon.name();
data.insert(std::make_pair("defender_weapon", item));
weapon_list.add_row(data);
}
assert(best_weapon < static_cast<int>(weapon_list.get_item_count()));
weapon_list.select_row(best_weapon);
}
void tunit_attack::pre_show(CVideo& /*video*/, twindow& window)
{
set_attacker_info(window, *attacker_itor_);
set_defender_info(window, *defender_itor_);
selected_weapon_ = -1;
set_weapon_info(window, weapons_, best_weapon_);
}
void tunit_attack::post_show(twindow& window)
{
if(get_retval() == twindow::OK) {
selected_weapon_ = find_widget<tlistbox>(&window, "weapon_list", false)
.get_selected_row();
}
}
} // namespace gui2

View file

@ -0,0 +1,68 @@
/* $Id$ */
/*
Copyright (C) 2010 by Mark de Wever <koraq@xs4all.nl>
Part of 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 version 2
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_ATTACK_HPP_INCLUDED
#define GUI_DIALOGS_UNIT_ATTACK_HPP_INCLUDED
#include "actions.hpp"
#include "gui/dialogs/dialog.hpp"
#include "unit_map.hpp"
namespace gui2 {
class tunit_attack
: public tdialog
{
public:
tunit_attack(
const unit_map::iterator& attacker_itor
, const unit_map::iterator& defender_itor
, const std::vector<battle_context>& weapons
, const int best_weapon);
/***** ***** ***** setters / getters for members ***** ****** *****/
int get_selected_weapon() const { return selected_weapon_; }
private:
/** Inherited from tdialog, implemented by REGISTER_WINDOW. */
virtual const std::string& window_id() const;
/** Inherited from tdialog. */
void pre_show(CVideo& video, twindow& window);
/** Inherited from tdialog. */
void post_show(twindow& window);
/** The index of the selected weapon. */
int selected_weapon_;
/** Iterator pointing to the attacker. */
unit_map::iterator attacker_itor_;
/** Iterator pointing to the defender. */
unit_map::iterator defender_itor_;
/** List of all battle contexts used for getting the weapons. */
std::vector<battle_context> weapons_;
/** The best weapon, aka the one high-lighted. */
int best_weapon_;
};
} // namespace gui2
#endif

View file

@ -23,6 +23,9 @@
#include "game_end_exceptions.hpp"
#include "game_events.hpp"
#include "gettext.hpp"
#include "gui/dialogs/unit_attack.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "log.hpp"
#include "map.hpp"
#include "marked-up_text.hpp"
@ -647,6 +650,30 @@ int mouse_handler::fill_weapon_choices(std::vector<battle_context>& bc_vector, u
int mouse_handler::show_attack_dialog(const map_location& attacker_loc, const map_location& defender_loc)
{
if(gui2::new_widgets) {
unit_map::iterator attacker = find_unit(attacker_loc);
unit_map::iterator defender = find_unit(defender_loc);
std::vector<battle_context> weapons;
const int best_weapon =
fill_weapon_choices(weapons, attacker, defender);
gui2::tunit_attack dlg(
attacker
, defender
, weapons
, best_weapon);
dlg.show(gui_->video());
if(dlg.get_retval() == gui2::twindow::OK) {
return dlg.get_selected_weapon();
} else {
return -1;
}
}
unit_map::iterator attacker = find_unit(attacker_loc);
unit_map::iterator defender = find_unit(defender_loc);