gui2/tgamestate_inspector: Add views for event and menu item handlers

This commit is contained in:
Ignacio R. Morelle 2015-08-20 05:42:57 -03:00
parent 6e0af4f77e
commit 636cc6315f
2 changed files with 123 additions and 0 deletions

View file

@ -44,6 +44,8 @@ Version 1.13.1+dev:
without #undef, to help detect unintentional name clashes.
* Fix macro definition line numbers being offset by 1 in WML preprocessor
messages involving macros.
* Added WML menu item and event handler views to the Gamestate Inspector
dialog.
* Editor:
* Added Category field and color sliders to the Edit Label panel.
* Miscellaneous and bug fixes:

View file

@ -29,6 +29,7 @@
#include "gui/widgets/window.hpp"
#include "desktop/clipboard.hpp"
#include "game_events/manager.hpp"
#include "serialization/parser.hpp" // for write()
#include "utils/foreach.tpp"
@ -307,7 +308,121 @@ public:
}
};
/**
* Controller for WML event and menu item handler views.
*/
class event_mode_controller : public single_mode_controller
{
public:
/** WML event handler tag identifier. */
enum HANDLER_TYPE
{
EVENT_HANDLER, /**< Standard WML event handler ([event]). */
WMI_HANDLER /**< WML menu item handler ([menu_item]). */
};
/**
* Constructor.
*
* @param name View name displayed on the UI.
* @param m Inspector model reference.
* @param wml_node WML node key. Should be either "event" or
* "menu_item".
*/
event_mode_controller(const std::string& name,
tgamestate_inspector::model& m,
HANDLER_TYPE handler_type)
: single_mode_controller(name, m)
, handler_type_(handler_type)
, pages_()
{
}
/**
* Populates the list of pages for this view.
*/
virtual void show_stuff_list()
{
assert(resources::game_events);
const std::string handler_key
= handler_type_ == WMI_HANDLER ? "menu_item" : "event";
model_.clear_stuff_list();
pages_.clear();
config events_config;
resources::game_events->write_events(events_config);
FOREACH(const AUTO & cfg, events_config.child_range(handler_key))
{
shared_string_ptr sstrp(new std::string(config_to_string(cfg)));
const std::string& wmltext = *sstrp;
const unsigned num_pages = model_.get_num_page(wmltext);
for(unsigned i = 0; i < num_pages; ++i) {
pages_.push_back(std::make_pair(sstrp, i));
std::ostringstream o;
if(handler_type_ == WMI_HANDLER) {
// [menu_item]
o << cfg["id"].str();
} else {
// [event]
o << cfg["name"].str();
if(!cfg["id"].empty()) {
o << " [id=\"" << cfg["id"].str() << "\"]";
}
}
if(num_pages > 1) {
o << " [page" << (i + 1) << '/' << num_pages << ']';
}
model_.add_row_to_stuff_list(o.str(), o.str());
}
}
model_.set_inspect_window_text("");
}
/**
* Updates the page display for the currently selected item in this view.
*/
virtual void handle_stuff_list_selection()
{
const int row = model_.stuff_list->get_selected_row();
if(row < 0 || size_t(row) >= pages_.size()) {
model_.set_inspect_window_text("");
return;
}
const page_descriptor& pd = pages_[size_t(row)];
model_.set_inspect_window_text(*pd.first, pd.second);
}
/**
* Updates the whole view (page list and page display).
*/
virtual void update_view_from_model()
{
show_stuff_list();
handle_stuff_list_selection();
}
private:
// Because of GUI2's limitations, we need to use set_inspect_window_text's
// option to split view pages into multiple subpages. Each of those
// subpages is built from a shared string object we cache beforehand for
// cycle efficiency. We use a vector of page content pointers/subpage
// number pairs matching the UI layout to keep things simple.
typedef boost::shared_ptr<std::string> shared_string_ptr;
typedef std::pair<shared_string_ptr, unsigned> page_descriptor;
HANDLER_TYPE handler_type_;
std::vector<page_descriptor> pages_;
};
class unit_mode_controller : public single_mode_controller
{
@ -537,6 +652,12 @@ public:
{
sm_controllers_.push_back(boost::shared_ptr<single_mode_controller>(
new variable_mode_controller("variables", model_)));
sm_controllers_.push_back(boost::shared_ptr<single_mode_controller>(
new event_mode_controller(
"events", model_, event_mode_controller::EVENT_HANDLER)));
sm_controllers_.push_back(boost::shared_ptr<single_mode_controller>(
new event_mode_controller(
"menu items", model_, event_mode_controller::WMI_HANDLER)));
sm_controllers_.push_back(boost::shared_ptr<single_mode_controller>(
new unit_mode_controller("units", model_)));
// BOOST_FOREACHteam