mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-04 18:43:24 +00:00
Support for [action] in theme WML.
[action] is the twin of [menu]. I splitted the codepaths for menu and action buttons.
This commit is contained in:
parent
c84190d3c5
commit
e014493923
@ -638,6 +638,19 @@ std::string get_names(HOTKEY_COMMAND id) {
|
||||
return boost::algorithm::join(names, ", ");
|
||||
}
|
||||
|
||||
std::string get_names(std::string id) {
|
||||
|
||||
std::vector<std::string> names;
|
||||
BOOST_FOREACH(const hotkey::hotkey_item& item, hotkeys_) {
|
||||
if (item.get_command() == id && (!item.null()) ) {
|
||||
names.push_back(item.get_name());
|
||||
}
|
||||
}
|
||||
|
||||
return boost::algorithm::join(names, ", ");
|
||||
}
|
||||
|
||||
|
||||
HOTKEY_COMMAND get_hotkey_command(const std::string& command)
|
||||
{
|
||||
if (command_map_.find(command) != command_map_.end()) {
|
||||
@ -1223,17 +1236,25 @@ void command_executor::set_button_state(display& disp) {
|
||||
|
||||
BOOST_FOREACH(const theme::menu& menu, disp.get_theme().menus()) {
|
||||
|
||||
if (menu.items().size() == 1) {
|
||||
hotkey::HOTKEY_COMMAND command = hotkey::get_id(menu.items().front());
|
||||
gui::button* button = disp.find_button(menu.get_id());
|
||||
bool enabled = false;
|
||||
BOOST_FOREACH(const std::string& command, menu.items()) {
|
||||
|
||||
ACTION_STATE state = get_action_state(command, -1);
|
||||
gui::button* button = disp.find_button(menu.get_id());
|
||||
button->enable(can_execute_command(command));
|
||||
hotkey::HOTKEY_COMMAND command_id = hotkey::get_id(command);
|
||||
std::string tooltip = menu.tooltip();
|
||||
|
||||
bool can_execute = can_execute_command(command_id);
|
||||
if (!can_execute) continue;
|
||||
enabled = true;
|
||||
|
||||
ACTION_STATE state = get_action_state(command_id, -1);
|
||||
switch (state) {
|
||||
case ACTION_SELECTED:
|
||||
case ACTION_ON:
|
||||
button->set_check(true);
|
||||
break;
|
||||
case ACTION_OFF:
|
||||
case ACTION_DESELECTED:
|
||||
button->set_check(false);
|
||||
break;
|
||||
case ACTION_STATELESS:
|
||||
@ -1241,23 +1262,29 @@ void command_executor::set_button_state(display& disp) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
button->enable(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void command_executor::show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui)
|
||||
void command_executor::show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool /*context_menu*/, display& gui)
|
||||
{
|
||||
std::vector<std::string> items = items_arg;
|
||||
if (items.empty()) {
|
||||
return;
|
||||
}
|
||||
//TODO this does not make sense anymore
|
||||
if (can_execute_command(hotkey::get_id(items.front()), 0)) {
|
||||
// If just one item is passed in, that means we should execute that item.
|
||||
/*
|
||||
if (!context_menu && items.size() == 1 && items_arg.size() == 1) {
|
||||
hotkey::execute_command(gui,hotkey::get_id(items.front()), this);
|
||||
set_button_state(gui);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
std::vector<std::string> menu = get_menu_images(gui, items);
|
||||
|
||||
@ -1278,11 +1305,53 @@ void command_executor::show_menu(const std::vector<std::string>& items_arg, int
|
||||
}
|
||||
}
|
||||
|
||||
std::string command_executor::get_menu_image(hotkey::HOTKEY_COMMAND command, int index) const {
|
||||
switch (get_action_state(command, index)) {
|
||||
case ACTION_ON: return game_config::images::checked_menu;
|
||||
case ACTION_OFF: return game_config::images::unchecked_menu;
|
||||
default: return get_action_image(command, index);
|
||||
void command_executor::execute_action(const std::vector<std::string>& items_arg, int /*xloc*/, int /*yloc*/, bool /*context_menu*/, display& gui)
|
||||
{
|
||||
std::vector<std::string> items = items_arg;
|
||||
if (items.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
hotkey::HOTKEY_COMMAND command;
|
||||
std::vector<std::string>::iterator i = items.begin();
|
||||
while(i != items.end()) {
|
||||
command = hotkey::get_id(*i);
|
||||
if (can_execute_command(command)) {
|
||||
hotkey::execute_command(gui, command, this);
|
||||
set_button_state(gui);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
std::string command_executor::get_menu_image(const std::string& command, int index) const {
|
||||
|
||||
const std::string base_image_name = "icons/action/" + command + "_25.png";
|
||||
const std::string pressed_image_name = "icons/action/" + command + "_25-pressed.png";
|
||||
|
||||
const hotkey::HOTKEY_COMMAND hk = hotkey::get_id(command);
|
||||
const hotkey::ACTION_STATE state = get_action_state(hk, index);
|
||||
|
||||
if (file_exists("images/" + base_image_name)) {
|
||||
switch (state) {
|
||||
case ACTION_ON:
|
||||
case ACTION_SELECTED:
|
||||
return pressed_image_name;
|
||||
default:
|
||||
return base_image_name;
|
||||
}
|
||||
}
|
||||
|
||||
switch (get_action_state(hk, index)) {
|
||||
case ACTION_ON:
|
||||
return game_config::images::checked_menu;
|
||||
case ACTION_OFF:
|
||||
return game_config::images::unchecked_menu;
|
||||
case ACTION_SELECTED:
|
||||
return game_config::images::selected_menu;
|
||||
case ACTION_DESELECTED:
|
||||
return game_config::images::deselected_menu;
|
||||
default: return get_action_image(hk, index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1296,7 +1365,7 @@ std::vector<std::string> command_executor::get_menu_images(display& disp, const
|
||||
|
||||
std::stringstream str;
|
||||
//see if this menu item has an associated image
|
||||
std::string img(get_menu_image(hk, i));
|
||||
std::string img(get_menu_image(item, i));
|
||||
if (img.empty() == false) {
|
||||
has_image = true;
|
||||
str << IMAGE_PREFIX << img << COLUMN_SEPARATOR;
|
||||
|
@ -287,11 +287,14 @@ void load_hotkeys(const config& cfg, bool set_as_default = false);
|
||||
void reset_default_hotkeys();
|
||||
void save_hotkeys(config& cfg);
|
||||
|
||||
//TODO they do the same?
|
||||
HOTKEY_COMMAND get_id(const std::string& command);
|
||||
HOTKEY_COMMAND get_hotkey_command(const std::string& command);
|
||||
const std::string get_description(const std::string& command);
|
||||
const std::string get_tooltip(const std::string& command);
|
||||
|
||||
std::string get_names(hotkey::HOTKEY_COMMAND id);
|
||||
std::string get_names(std::string id);
|
||||
void add_hotkey(const hotkey_item& item);
|
||||
void clear_hotkeys(const std::string& command);
|
||||
|
||||
@ -305,11 +308,10 @@ hotkey_item& get_hotkey(const SDL_JoyButtonEvent& event);
|
||||
hotkey_item& get_hotkey(const SDL_JoyHatEvent& event);
|
||||
hotkey_item& get_hotkey(const SDL_KeyboardEvent& event);
|
||||
|
||||
HOTKEY_COMMAND get_hotkey_command(const std::string& command);
|
||||
|
||||
std::vector<hotkey_item>& get_hotkeys();
|
||||
|
||||
enum ACTION_STATE { ACTION_STATELESS, ACTION_ON, ACTION_OFF };
|
||||
enum ACTION_STATE { ACTION_STATELESS, ACTION_ON, ACTION_OFF, ACTION_SELECTED, ACTION_DESELECTED };
|
||||
|
||||
// Abstract base class for objects that implement the ability
|
||||
// to execute hotkey commands.
|
||||
@ -387,11 +389,12 @@ public:
|
||||
// Does the action control a toggle switch? If so, return the state of the action (on or off).
|
||||
virtual ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND /*command*/, int /*index*/) const { return ACTION_STATELESS; }
|
||||
// Returns the appropriate menu image. Checkable items will get a checked/unchecked image.
|
||||
std::string get_menu_image(hotkey::HOTKEY_COMMAND command, int index=-1) const;
|
||||
std::string get_menu_image(const std::string& command, int index=-1) const;
|
||||
// Returns a vector of images for a given menu.
|
||||
std::vector<std::string> get_menu_images(display &, const std::vector<std::string>& items_arg);
|
||||
|
||||
void show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui);
|
||||
void execute_action(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui);
|
||||
|
||||
/**
|
||||
* Adjusts the state of those theme menu buttons which trigger hotkey events.
|
||||
|
@ -505,20 +505,46 @@ theme::menu::menu() :
|
||||
title_(),
|
||||
tooltip_(),
|
||||
image_(),
|
||||
type_(),
|
||||
overlay_(),
|
||||
items_()
|
||||
{}
|
||||
|
||||
theme::menu::menu(const config &cfg):
|
||||
object(cfg), context_(cfg["is_context_menu"].to_bool()),
|
||||
title_(cfg["title"].str() + cfg["title_literal"].str()),
|
||||
tooltip_(cfg["tooltip"]), image_(cfg["image"]), type_(cfg["type"]),
|
||||
tooltip_(cfg["tooltip"]), image_(cfg["image"]), overlay_(cfg["overlay"]),
|
||||
items_(utils::split(cfg["items"]))
|
||||
{
|
||||
if (cfg["auto_tooltip"].to_bool() && tooltip_.empty() && items_.size() == 1) {
|
||||
tooltip_ = hotkey::get_description(items_[0]);
|
||||
tooltip_ = hotkey::get_description(items_[0])
|
||||
+ hotkey::get_names(items_[0]) + "\n" + hotkey::get_tooltip(items_[0]);
|
||||
} else if (cfg["tooltip_name_prepend"].to_bool() && items_.size() == 1) {
|
||||
tooltip_ = hotkey::get_description(items_[0]) + "\n" + tooltip_;
|
||||
tooltip_ = hotkey::get_description(items_[0])
|
||||
+ hotkey::get_names(items_[0]) + "\n" + tooltip_;
|
||||
}
|
||||
}
|
||||
|
||||
theme::action::action() :
|
||||
object(),
|
||||
context_(false),
|
||||
title_(),
|
||||
tooltip_(),
|
||||
image_(),
|
||||
overlay_(),
|
||||
type_(),
|
||||
items_()
|
||||
{}
|
||||
|
||||
theme::action::action(const config &cfg):
|
||||
object(cfg), context_(cfg["is_context_menu"].to_bool()),
|
||||
title_(cfg["title"].str() + cfg["title_literal"].str()),
|
||||
tooltip_(cfg["tooltip"]), image_(cfg["image"]), overlay_(cfg["overlay"]), type_(cfg["type"]),
|
||||
items_(utils::split(cfg["items"]))
|
||||
{
|
||||
if (cfg["auto_tooltip"].to_bool() && tooltip_.empty() && items_.size() == 1) {
|
||||
tooltip_ = hotkey::get_description(items_[0]) + " hotkeys: " + hotkey::get_names(items_[0]) + "\n" + hotkey::get_tooltip(items_[0]);
|
||||
} else if (cfg["tooltip_name_prepend"].to_bool() && items_.size() == 1) {
|
||||
tooltip_ = hotkey::get_description(items_[0]) + " hotkeys: " + hotkey::get_names(items_[0]) + "\n" + tooltip_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,6 +555,7 @@ theme::theme(const config& cfg, const SDL_Rect& screen) :
|
||||
panels_(),
|
||||
labels_(),
|
||||
menus_(),
|
||||
actions_(),
|
||||
context_(),
|
||||
status_(),
|
||||
main_map_(),
|
||||
@ -586,6 +613,7 @@ bool theme::set_resolution(const SDL_Rect& screen)
|
||||
labels_.clear();
|
||||
status_.clear();
|
||||
menus_.clear();
|
||||
actions_.clear();
|
||||
|
||||
add_object(*current);
|
||||
|
||||
@ -651,6 +679,20 @@ void theme::add_object(const config& cfg)
|
||||
DBG_DP << "done adding menu...\n";
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const config &a, cfg.child_range("action"))
|
||||
{
|
||||
action new_action(a);
|
||||
DBG_DP << "adding action: " << (new_action.is_context() ? "is context" : "not context") << "\n";
|
||||
if(new_action.is_context())
|
||||
action_context_ = new_action;
|
||||
else{
|
||||
set_object_location(new_action, a["rect"], a["ref"]);
|
||||
actions_.push_back(new_action);
|
||||
}
|
||||
|
||||
DBG_DP << "done adding action...\n";
|
||||
}
|
||||
|
||||
if (const config &c = cfg.child("main_map_border")) {
|
||||
border_ = tborder(c);
|
||||
} else {
|
||||
@ -677,6 +719,12 @@ void theme::remove_object(std::string id){
|
||||
return;
|
||||
}
|
||||
}
|
||||
for(std::vector<theme::action>::iterator a = actions_.begin(); a != actions_.end(); ++a) {
|
||||
if (a->get_id() == id){
|
||||
actions_.erase(a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void theme::set_object_location(theme::object& element, std::string rect_str, std::string ref_id){
|
||||
@ -702,6 +750,12 @@ void theme::modify(const config &cfg)
|
||||
title_stash[m->get_id()] = m->title();
|
||||
}
|
||||
|
||||
std::vector<theme::action>::iterator a;
|
||||
for (a = actions_.begin(); a != actions_.end(); ++a) {
|
||||
if (!a->title().empty() && !a->get_id().empty())
|
||||
title_stash[a->get_id()] = a->title();
|
||||
}
|
||||
|
||||
// Change existing theme objects.
|
||||
BOOST_FOREACH(const config &c, cfg.child_range("change"))
|
||||
{
|
||||
@ -726,6 +780,10 @@ void theme::modify(const config &cfg)
|
||||
if (title_stash.find(m->get_id()) != title_stash.end())
|
||||
m->set_title(title_stash[m->get_id()]);
|
||||
}
|
||||
for (a = actions_.begin(); a != actions_.end(); ++a) {
|
||||
if (title_stash.find(a->get_id()) != title_stash.end())
|
||||
a->set_title(title_stash[a->get_id()]);
|
||||
}
|
||||
}
|
||||
|
||||
theme::object& theme::find_element(std::string id){
|
||||
@ -740,6 +798,9 @@ theme::object& theme::find_element(std::string id){
|
||||
for (std::vector<theme::menu>::iterator m = menus_.begin(); m != menus_.end(); ++m){
|
||||
if (m->get_id() == id) { res = &(*m); }
|
||||
}
|
||||
for (std::vector<theme::action>::iterator a = actions_.begin(); a != actions_.end(); ++a){
|
||||
if (a->get_id() == id) { res = &(*a); }
|
||||
}
|
||||
if (id == "main-map") { res = &main_map_; }
|
||||
if (id == "mini-map") { res = &mini_map_; }
|
||||
if (id == "palette") { res = &palette_; }
|
||||
|
@ -163,6 +163,35 @@ public:
|
||||
std::string image_;
|
||||
};
|
||||
|
||||
class action : public object
|
||||
{
|
||||
public:
|
||||
action();
|
||||
explicit action(const config& cfg);
|
||||
|
||||
using object::location;
|
||||
|
||||
bool is_context() const { return context_; }
|
||||
|
||||
const std::string& title() const { return title_; }
|
||||
|
||||
const std::string& tooltip() const { return tooltip_; }
|
||||
|
||||
const std::string& type() const { return type_; }
|
||||
|
||||
const std::string& image() const { return image_; }
|
||||
|
||||
const std::string& overlay() const { return overlay_; }
|
||||
|
||||
const std::vector<std::string>& items() const { return items_; }
|
||||
|
||||
void set_title(const std::string& new_title) { title_ = new_title; }
|
||||
private:
|
||||
bool context_;
|
||||
std::string title_, tooltip_, image_, overlay_, type_;
|
||||
std::vector<std::string> items_;
|
||||
};
|
||||
|
||||
class menu : public object
|
||||
{
|
||||
public:
|
||||
@ -177,16 +206,16 @@ public:
|
||||
|
||||
const std::string& tooltip() const { return tooltip_; }
|
||||
|
||||
const std::string& type() const { return type_; }
|
||||
|
||||
const std::string& image() const { return image_; }
|
||||
|
||||
const std::string& overlay() const { return overlay_; }
|
||||
|
||||
const std::vector<std::string>& items() const { return items_; }
|
||||
|
||||
void set_title(const std::string& new_title) { title_ = new_title; }
|
||||
private:
|
||||
bool context_;
|
||||
std::string title_, tooltip_, image_, type_;
|
||||
std::string title_, tooltip_, image_, overlay_;
|
||||
std::vector<std::string> items_;
|
||||
};
|
||||
|
||||
@ -197,6 +226,7 @@ public:
|
||||
const std::vector<panel>& panels() const { return panels_; }
|
||||
const std::vector<label>& labels() const { return labels_; }
|
||||
const std::vector<menu>& menus() const { return menus_; }
|
||||
const std::vector<action>& actions() const { return actions_; }
|
||||
|
||||
const menu* context_menu() const
|
||||
{ return context_.is_context() ? &context_ : NULL; }
|
||||
@ -242,8 +272,10 @@ private:
|
||||
std::vector<panel> panels_;
|
||||
std::vector<label> labels_;
|
||||
std::vector<menu> menus_;
|
||||
std::vector<action> actions_;
|
||||
|
||||
menu context_;
|
||||
action action_context_;
|
||||
|
||||
std::map<std::string,status_item> status_;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user