Merge branch 'wmi_pager'
This commit is contained in:
commit
d684826446
11 changed files with 216 additions and 16 deletions
|
@ -1123,6 +1123,8 @@
|
|||
<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" />
|
||||
|
|
|
@ -21288,6 +21288,14 @@
|
|||
RelativePath="..\..\src\notifications\windows_tray_notification.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\wmi_pager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\wmi_pager.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\wml_exception.cpp"
|
||||
>
|
||||
|
|
|
@ -916,6 +916,7 @@ set(wesnoth-main_SRC
|
|||
whiteboard/side_actions.cpp
|
||||
whiteboard/suppose_dead.cpp
|
||||
whiteboard/utility.cpp
|
||||
wmi_pager.cpp
|
||||
${network_implementation_files} # network.cpp and network_worker.cpp are included by default (without USE_ANA_NETWORK)
|
||||
)
|
||||
|
||||
|
|
|
@ -553,6 +553,7 @@ wesnoth_sources = Split("""
|
|||
widgets/combo_drag.cpp
|
||||
widgets/drop_target.cpp
|
||||
widgets/scrollpane.cpp
|
||||
wmi_pager.cpp
|
||||
""")
|
||||
|
||||
if env["PLATFORM"] == "win32":
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
wml_menu_item(const std::string& id, const vconfig & definition,
|
||||
const wml_menu_item & original);
|
||||
|
||||
/// The id of this item.
|
||||
const std::string & id() const { return item_id_; }
|
||||
/// The image associated with this menu item.
|
||||
const std::string & image() const;
|
||||
/// If true, allow using the menu to trigger this item.
|
||||
|
|
|
@ -34,9 +34,6 @@ static lg::log_domain log_engine("engine");
|
|||
#define WRN_NG LOG_STREAM(warn, log_engine)
|
||||
#define LOG_NG LOG_STREAM(info, log_engine)
|
||||
|
||||
static const size_t MAX_WML_COMMANDS = 7;
|
||||
|
||||
|
||||
// This file is in the game_events namespace.
|
||||
namespace game_events
|
||||
{
|
||||
|
@ -104,16 +101,14 @@ 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.
|
||||
* The number of items returned is limited by MAX_WML_COMMANDS.
|
||||
* 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 @descriptions (in the same order as @a items).
|
||||
*/
|
||||
void wmi_container::get_items(const map_location& hex,
|
||||
std::vector<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions) const
|
||||
std::vector<std::string> & descriptions, const_iterator start, const_iterator finish) const
|
||||
{
|
||||
size_t item_count = 0;
|
||||
|
||||
if ( empty() )
|
||||
// Nothing to do (skip setting game variables).
|
||||
return;
|
||||
|
@ -124,7 +119,7 @@ void wmi_container::get_items(const map_location& hex,
|
|||
scoped_xy_unit highlighted_unit("unit", hex.x, hex.y, *resources::units);
|
||||
|
||||
// Check each menu item.
|
||||
BOOST_FOREACH( const item_ptr & item, *this )
|
||||
BOOST_FOREACH( const item_ptr & item, std::make_pair<const_iterator> (start, finish) )
|
||||
{
|
||||
// Can this item be shown?
|
||||
if ( item->use_wml_menu() && item->can_show(hex) )
|
||||
|
@ -132,10 +127,6 @@ void wmi_container::get_items(const map_location& hex,
|
|||
// Include this item.
|
||||
items.push_back(item);
|
||||
descriptions.push_back(item->menu_text());
|
||||
|
||||
// Limit how many items can be returned.
|
||||
if ( ++item_count >= MAX_WML_COMMANDS )
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,8 +76,15 @@ public:
|
|||
bool fire_item(const std::string & id, const map_location & hex) const;
|
||||
/// Returns the menu items that can be shown for the given location.
|
||||
void get_items(const map_location& hex,
|
||||
std::vector<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions) const;
|
||||
std::vector<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions,
|
||||
const_iterator start, const_iterator finish) const;
|
||||
/// Range over all items by default
|
||||
void get_items(const map_location& hex,
|
||||
std::vector<boost::shared_ptr<const wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions) const {
|
||||
get_items(hex, items, descriptions, begin(), end());
|
||||
}
|
||||
/// Initializes the implicit event handlers for inlined [command]s.
|
||||
void init_handlers() const;
|
||||
void to_config(config& cfg) const;
|
||||
|
@ -99,6 +106,7 @@ public:
|
|||
const_iterator begin() const { return const_iterator(wml_menu_items_.begin()); }
|
||||
const_iterator end() const { return const_iterator(wml_menu_items_.end()); }
|
||||
|
||||
size_t size() const { return wml_menu_items_.size(); }
|
||||
private: // data
|
||||
map_t wml_menu_items_;
|
||||
};
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "unit.hpp"
|
||||
#include "unit_id.hpp"
|
||||
#include "whiteboard/manager.hpp"
|
||||
#include "wmi_pager.hpp"
|
||||
#include "wml_exception.hpp"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -125,6 +126,7 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
|
|||
init_side_done_(level["init_side_done"].to_bool(true)),
|
||||
savenames_(),
|
||||
wml_commands_(),
|
||||
wml_command_pager_(new wmi_pager()),
|
||||
victory_when_enemies_defeated_(true),
|
||||
remove_from_carryover_on_defeat_(true),
|
||||
end_level_data_(),
|
||||
|
@ -724,7 +726,9 @@ bool play_controller::execute_command(const hotkey::hotkey_command& cmd, int ind
|
|||
throw game::load_game_exception(savenames_[i],false,false,false,"");
|
||||
|
||||
} else if ( i < wml_commands_.size() && wml_commands_[i] ) {
|
||||
wml_commands_[i]->fire_event(mouse_handler_.get_last_hex());
|
||||
if (!wml_command_pager_->capture(*wml_commands_[i])) {
|
||||
wml_commands_[i]->fire_event(mouse_handler_.get_last_hex());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1072,7 +1076,8 @@ void play_controller::expand_wml_commands(std::vector<std::string>& items)
|
|||
|
||||
// Replace this placeholder entry with available menu items.
|
||||
items.erase(items.begin() + i);
|
||||
gamestate_.gamedata_.get_wml_menu_items().get_items(mouse_handler_.get_last_hex(),
|
||||
wml_command_pager_->update_ref(&gamestate_.gamedata_.get_wml_menu_items());
|
||||
wml_command_pager_->get_items(mouse_handler_.get_last_hex(),
|
||||
wml_commands_, newitems);
|
||||
items.insert(items.begin()+i, newitems.begin(), newitems.end());
|
||||
// End the "for" loop.
|
||||
|
|
|
@ -35,6 +35,7 @@ class saved_game;
|
|||
class game_data;
|
||||
class team;
|
||||
class unit;
|
||||
class wmi_pager;
|
||||
|
||||
namespace actions {
|
||||
class undo_list;
|
||||
|
@ -279,6 +280,7 @@ private:
|
|||
|
||||
void expand_wml_commands(std::vector<std::string>& items);
|
||||
std::vector<const_item_ptr> wml_commands_;
|
||||
boost::scoped_ptr<wmi_pager> wml_command_pager_;
|
||||
|
||||
bool victory_when_enemies_defeated_;
|
||||
bool remove_from_carryover_on_defeat_;
|
||||
|
|
131
src/wmi_pager.cpp
Normal file
131
src/wmi_pager.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
Copyright (C) 2014 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 "gettext.hpp"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#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<boost::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(boost::make_shared<const game_events::wml_menu_item>(next_id, temp));
|
||||
descriptions.push_back(desc);
|
||||
}
|
||||
|
||||
static void add_prev_page_item( std::vector<boost::shared_ptr<const game_events::wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions)
|
||||
{
|
||||
std::string desc = _("Earlier Items");
|
||||
config temp;
|
||||
temp["description"] = desc;
|
||||
items.push_back(boost::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 game_events::wmi_container::const_iterator wmi_it;
|
||||
|
||||
void wmi_pager::get_items(const map_location& hex,
|
||||
std::vector<boost::shared_ptr<const game_events::wml_menu_item> > & items,
|
||||
std::vector<std::string> & descriptions)
|
||||
{
|
||||
if (!foo_) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(page_size_ > 2u); //if we dont have at least 3 items, we can't display anything...
|
||||
|
||||
if (foo_->size() <= page_size_) { //In this case the first page is sufficient and we don't have to do anything.
|
||||
foo_->get_items(hex, items, descriptions);
|
||||
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 = foo_->begin();
|
||||
std::advance(end_first_page, page_size_ - 1);
|
||||
|
||||
foo_->get_items(hex, items, descriptions, foo_->begin(), end_first_page);
|
||||
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 >= foo_->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 foo_->size() > page_size_ or else we exited earlier, and we only decrease by (page_size_-2) each time.
|
||||
|
||||
wmi_it start_range = foo_->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
|
||||
//^ = foo_->begin() + first_displayed_index
|
||||
|
||||
if (first_displayed_index + page_size_-1 >= foo_->size()) //if this can be the last page, then we won't put next page at the bottom.
|
||||
{
|
||||
foo_->get_items(hex, items, descriptions, start_range, foo_->end()); // display all of the remaining items
|
||||
return;
|
||||
} else { //we are in a middle page
|
||||
wmi_it end_range = start_range;
|
||||
std::advance(end_range, page_size_-2);
|
||||
|
||||
foo_->get_items(hex, items, descriptions, start_range, end_range);
|
||||
add_next_page_item(items, descriptions);
|
||||
return;
|
||||
}
|
||||
}
|
49
src/wmi_pager.hpp
Normal file
49
src/wmi_pager.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
struct map_location;
|
||||
namespace game_events { class wml_menu_item; }
|
||||
namespace game_events { class wmi_container; }
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class wmi_pager {
|
||||
private:
|
||||
int page_num_; //!< Current page number
|
||||
size_t page_size_; //!< Current size of a page
|
||||
const game_events::wmi_container * foo_; //!< Internal pointer to the collection of wml menu items
|
||||
|
||||
public:
|
||||
wmi_pager() : page_num_(0), page_size_(7), foo_(NULL) {}
|
||||
|
||||
void update_ref(game_events::wmi_container * ptr) { foo_ = 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
|
||||
std::vector<boost::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