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:
parent
f338c48863
commit
507d00d9d9
13 changed files with 17 additions and 277 deletions
|
@ -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"
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
@ -587,7 +587,6 @@ wesnoth_sources = Split("""
|
|||
widgets/combo.cpp
|
||||
widgets/drop_target.cpp
|
||||
widgets/scrollpane.cpp
|
||||
wmi_pager.cpp
|
||||
""")
|
||||
|
||||
if env["PLATFORM"] == "win32":
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
};
|
Loading…
Add table
Reference in a new issue