Refactored out wmi_pager

This is no longer needed after switching right-click menus to GUI2, since they have built-in
scrolling capability. This also removes the max_wml_menu_items preference.
This commit is contained in:
Charles Dang 2016-08-29 15:38:52 +11:00
parent f338c48863
commit 507d00d9d9
13 changed files with 17 additions and 277 deletions

View file

@ -109,18 +109,6 @@
step=1
[/advanced_preference]
[advanced_preference]
field=max_wml_menu_items
# TODO: It would be better to eliminate this preference and have it instead determined by the gui layout algorithm.
name=_ "Maximum WML menu items"
description= _ "Maximum number of WML-defined menu items displayed at once"
type=int
default=7
min=3
max=32
step=1
[/advanced_preference]
[advanced_preference]
field=use_twelve_hour_clock_format
name= _ "Use 12-hour clock format"

View file

@ -1158,8 +1158,6 @@
<Unit filename="../../src/widgets/textbox.hpp" />
<Unit filename="../../src/widgets/widget.cpp" />
<Unit filename="../../src/widgets/widget.hpp" />
<Unit filename="../../src/wmi_pager.cpp" />
<Unit filename="../../src/wmi_pager.hpp" />
<Unit filename="../../src/wml_exception.cpp" />
<Unit filename="../../src/wml_exception.hpp" />
<Unit filename="../../src/wml_separators.hpp" />

View file

@ -980,7 +980,6 @@ set(wesnoth-main_SRC
whiteboard/side_actions.cpp
whiteboard/suppose_dead.cpp
whiteboard/utility.cpp
wmi_pager.cpp
${network_implementation_files}
)

View file

@ -587,7 +587,6 @@ wesnoth_sources = Split("""
widgets/combo.cpp
widgets/drop_target.cpp
widgets/scrollpane.cpp
wmi_pager.cpp
""")
if env["PLATFORM"] == "win32":

View file

@ -101,35 +101,37 @@ bool wmi_container::fire_item(const std::string & id, const map_location & hex,
/**
* Returns the menu items that can be shown for the given location.
* Should be used with a wmi_pager to limit the number of items displayed at once.
*
* @param[out] items Pointers to applicable menu items will be pushed onto @a items.
* @param[out] descriptions Menu item text will be pushed onto @a descriptions (in the same order as @a items).
*/
std::vector<std::pair<std::shared_ptr<const wml_menu_item>, std::string> > wmi_container::get_items(const map_location& hex,
game_data & gamedata, filter_context & fc, unit_map & units, const_iterator start, const_iterator finish) const
void wmi_container::get_items(const map_location& hex,
std::vector<std::shared_ptr<const wml_menu_item>>& items,
std::vector<std::string>& descriptions,
filter_context& fc, game_data& gamedata, unit_map& units) const
{
std::vector<std::pair<std::shared_ptr<const wml_menu_item>, std::string> > ret;
if ( empty() ) {
// Nothing to do (skip setting game variables).
return ret;
return;
}
// Prepare for can show().
gamedata.get_variable("x1") = hex.x + 1;
gamedata.get_variable("y1") = hex.y + 1;
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, units);
// Check each menu item.
for (const item_ptr & item : std::make_pair (start, finish))
for (const item_ptr & item : *this)
{
// Can this item be shown?
if ( item->use_wml_menu() && (!item->is_synced() || resources::controller->can_use_synced_wml_menu()) && item->can_show(hex, gamedata, fc) )
{
// Include this item.
ret.push_back(std::make_pair(item, item->menu_text()));
items.push_back(item);
descriptions.push_back(item->menu_text());
}
}
return ret;
return;
}
/**

View file

@ -78,12 +78,10 @@ public:
/// Fires the menu item with the given @a id.
bool fire_item(const std::string & id, const map_location & hex, game_data & gamedata, filter_context & fc, unit_map & units) const;
/// Returns the menu items that can be shown for the given location.
std::vector<std::pair<std::shared_ptr<const wml_menu_item>, std::string> > get_items(const map_location& hex,
game_data & gamedata, filter_context & fc, unit_map & units, const_iterator start, const_iterator finish) const;
/// Range over all items by default
std::vector<std::pair<std::shared_ptr<const wml_menu_item>, std::string> > get_items(const map_location& hex, game_data & gamedata, filter_context & fc, unit_map & units) const {
return get_items(hex, gamedata, fc, units, begin(), end());
}
void get_items(const map_location& hex,
std::vector<std::shared_ptr<const wml_menu_item>>& items,
std::vector<std::string>& descriptions,
filter_context& fc, game_data& gamedata, unit_map& units) const;
/// Initializes the implicit event handlers for inlined [command]s.
void init_handlers() const;
void to_config(config& cfg) const;

View file

@ -1076,16 +1076,6 @@ int chat_message_aging()
return lexical_cast_default<int>(preferences::get("chat_message_aging"), 20);
}
void set_max_wml_menu_items(int max)
{
preferences::set("max_wml_menu_items", max);
}
int max_wml_menu_items()
{
return lexical_cast_default<int>(preferences::get("max_wml_menu_items"), 7);
}
bool show_all_units_in_help() {
return preferences::get("show_all_units_in_help", false);
}

View file

@ -253,9 +253,6 @@ class acquaintance;
int chat_message_aging();
void set_chat_message_aging(const int aging);
int max_wml_menu_items();
void set_max_wml_menu_items(int max);
bool show_all_units_in_help();
void set_show_all_units_in_help(bool value);

View file

@ -29,7 +29,6 @@
#include "savegame.hpp"
#include "saved_game.hpp"
#include "whiteboard/manager.hpp"
#include "wmi_pager.hpp"
#include "units/unit.hpp"
@ -42,7 +41,6 @@ play_controller::hotkey_handler::hotkey_handler(play_controller & pc, saved_game
, saved_game_(sg)
, savenames_()
, wml_commands_()
, wml_command_pager_(new wmi_pager())
, last_context_menu_x_(0)
, last_context_menu_y_(0)
{}
@ -247,11 +245,7 @@ bool play_controller::hotkey_handler::execute_command(const hotkey::hotkey_comma
load_autosave(savenames_[i]);
} else if ( i < wml_commands_.size() && wml_commands_[i] ) {
if (!wml_command_pager_->capture(*wml_commands_[i])) {
wml_commands_[i]->fire_event(mouse_handler_.get_last_hex(), gamestate().gamedata_);
} else { //relaunch the menu
show_menu(gui()->get_theme().context_menu()->items(),last_context_menu_x_,last_context_menu_y_,true, *gui());
}
wml_commands_[i]->fire_event(mouse_handler_.get_last_hex(), gamestate().gamedata_);
return true;
}
}
@ -426,10 +420,8 @@ void play_controller::hotkey_handler::expand_wml_commands(std::vector<std::strin
// Replace this placeholder entry with available menu items.
items.erase(items.begin() + i);
wml_command_pager_->update_ref(&gamestate().get_wml_menu_items());
wml_command_pager_->get_items(mouse_handler_.get_last_hex(),
gamestate().gamedata_, gamestate(), gamestate().board_.units_,
wml_commands_, newitems);
gamestate().get_wml_menu_items().get_items(mouse_handler_.get_last_hex(), wml_commands_, newitems,
gamestate(), gamestate().gamedata_, gamestate().board_.units_);
items.insert(items.begin()+i, newitems.begin(), newitems.end());
// End the "for" loop.
break;

View file

@ -30,7 +30,6 @@ namespace game_events { class wml_menu_item; }
class game_display;
class game_state;
class saved_game;
class wmi_pager;
class team;
@ -67,7 +66,6 @@ private:
*/
void expand_wml_commands(std::vector<std::string>& items);
std::vector<const_item_ptr> wml_commands_;
const std::unique_ptr<wmi_pager> wml_command_pager_;
int last_context_menu_x_;
int last_context_menu_y_;

View file

@ -34,7 +34,6 @@ class game_display;
class game_data;
class team;
class unit;
class wmi_pager;
class replay;
class saved_game;
struct mp_game_settings;

View file

@ -1,164 +0,0 @@
/*
Copyright (C) 2014 - 2016 by Chris Beck <render787@gmail.com>
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 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.
*/
#include "wmi_pager.hpp"
#include "global.hpp"
#include "config.hpp"
#include "game_events/menu_item.hpp"
#include "game_events/wmi_container.hpp"
#include "game_preferences.hpp"
#include "gettext.hpp"
#include <algorithm> //std::transform
#include <cassert>
#include <iterator> //std::advance
#include <string>
#include <vector>
struct map_location;
static const char * next_id = "__wml_items_next_page";
static const char * prev_id = "__wml_items_prev_page";
static void add_next_page_item( std::vector<std::shared_ptr<const game_events::wml_menu_item> > & items,
std::vector<std::string> & descriptions)
{
std::string desc = _("More Items");
config temp;
temp["description"] = desc;
items.push_back(std::make_shared<const game_events::wml_menu_item>(next_id, temp));
descriptions.push_back(desc);
}
static void add_prev_page_item( std::vector<std::shared_ptr<const game_events::wml_menu_item> > & items,
std::vector<std::string> & descriptions)
{
std::string desc = _("Previous Items");
config temp;
temp["description"] = desc;
items.push_back(std::make_shared<const game_events::wml_menu_item>(prev_id, temp));
descriptions.push_back(desc);
}
bool wmi_pager::capture ( const game_events::wml_menu_item & item )
{
if (item.id() == next_id) {
page_num_++;
return true;
} else if (item.id() == prev_id) {
page_num_--;
return true;
}
return false;
}
typedef std::shared_ptr<const game_events::wml_menu_item> wmi_ptr;
typedef std::pair<wmi_ptr, std::string> wmi_pair;
typedef std::vector<wmi_pair>::iterator wmi_it;
static wmi_ptr select_first(const wmi_pair & p)
{
return p.first;
}
static std::string select_second(const wmi_pair & p)
{
return p.second;
}
void wmi_pager::get_items(const map_location& hex,
game_data & gamedata, filter_context & fc, unit_map & units,
std::vector<wmi_ptr > & items,
std::vector<std::string> & descriptions)
{
if (!wmi_container_) {
return;
}
const int page_size_int = preferences::max_wml_menu_items();
assert(page_size_int >= 0 && "max wml menu items cannot be negative, this indicates preferences corruption");
const size_t page_size = page_size_int;
assert(page_size > 2u && "if we dont have at least 3 items, we can't display anything on a middle page...");
std::vector<wmi_pair > new_items = wmi_container_->get_items(hex, gamedata, fc, units);
if (new_items.size() <= page_size) { //In this case the first page is sufficient and we don't have to do anything.
std::transform(new_items.begin(), new_items.end(), back_inserter(items), select_first);
std::transform(new_items.begin(), new_items.end(), back_inserter(descriptions), select_second);
page_num_ = 0; //reset page num in case there are more items later.
return;
}
if (page_num_ < 0) //should never happen but maybe some wierd gui thing happens idk
{
page_num_ = 0;
}
if (page_num_ == 0) { //we are on the first page, so show page_size-1 items and a next button
wmi_it end_first_page = new_items.begin();
std::advance(end_first_page, page_size - 1);
std::transform(new_items.begin(), end_first_page, back_inserter(items), select_first);
std::transform(new_items.begin(), end_first_page, back_inserter(descriptions), select_second);
add_next_page_item(items, descriptions);
return;
}
add_prev_page_item(items, descriptions); //this will be necessary since we aren't on the first page
// first page has page_size - 1.
// last page has page_size - 1.
// all other pages have page_size - 2;
size_t first_displayed_index = (page_size - 2) * page_num_ + 1; //this is the 0-based index of the first item displayed on this page.
//alternatively, the number of items displayed on earlier pages
while (first_displayed_index >= new_items.size())
{
page_num_--; //The list must have gotten shorter and our page counter is now off the end, so decrement
first_displayed_index = (page_size - 2) * page_num_ + 1; //recalculate
}
// ^ This loop terminates with first_displayed_index > 0, because new_items.size() > page_size or else we exited earlier, and we only decrease by (page_size-2) each time.
if (first_displayed_index + page_size-1 >= new_items.size()) //if this can be the last page, then we won't put next page at the bottom.
{
//The last page we treat differently -- we always want to display (page_size) entries, to prevent resizing the context menu, so count back from end.
wmi_it end_range = new_items.end(); // It doesn't really matter if we display some entries that appeared on the previous page by doing this.
wmi_it start_range = end_range;
std::advance(start_range, -static_cast<signed int>(page_size-1));
std::transform(start_range, end_range, back_inserter(items), select_first);
std::transform(start_range, end_range, back_inserter(descriptions), select_second);
return;
} else { //we are in a middle page
wmi_it start_range = new_items.begin();
std::advance(start_range, first_displayed_index); // <-- get an iterator to the start of our range. begin() + n doesn't work because map is not random access
wmi_it end_range = start_range;
std::advance(end_range, page_size-2);
std::transform(start_range, end_range, back_inserter(items), select_first);
std::transform(start_range, end_range, back_inserter(descriptions), select_second);
add_next_page_item(items, descriptions);
return;
}
}

View file

@ -1,56 +0,0 @@
/*
Copyright (C) 2014 - 2016 by Chris Beck <render787@gmail.com>
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 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.
*/
/** This class manages the paging of WML menu items results, from a
* container. It is an adapter, managing the production of items lists
* from the container, and screening the "fire" signals coming back
* in to intercept the paging signals.
*
* TODO: Implement this as a helper class for menu perhaps, so that it
* can interact with the gui layout algorithm.
*/
class filter_context;
class game_data;
class game_state;
struct map_location;
class unit_map;
namespace game_events { class wml_menu_item; }
namespace game_events { class wmi_container; }
#include "global.hpp"
#include <memory>
#include <string>
#include <vector>
class wmi_pager {
private:
int page_num_; //!< Current page number
const game_events::wmi_container * wmi_container_; //!< Internal pointer to the collection of wml menu items
public:
wmi_pager() : page_num_(0), wmi_container_(nullptr) {}
void update_ref(game_events::wmi_container * ptr) { wmi_container_ = ptr; } //!< Updates the internal wmi_container pointer
/** Adds the currently paged range of menu items to the given lists */
void get_items(const map_location& hex, //!< Game hex related to this context menu
game_data & gamedata, filter_context & fc, unit_map & units, //!< Data needed to create scoped objects when evaluating wml filters
std::vector<std::shared_ptr<const game_events::wml_menu_item> > & items, //!< List of accumulated menu items so far.
std::vector<std::string> & descriptions); //!< List of menu item descriptions
bool capture(const game_events::wml_menu_item & item); //!< Captures a page up / page down event in the case that it is fired.
};