Merge pull request #895 from gfgtdf/master

This commit is contained in:
gfgtdf 2016-12-07 04:14:03 +01:00 committed by GitHub
commit 1202eb160e
8 changed files with 87 additions and 68 deletions

View file

@ -41,18 +41,9 @@
{ \
register_helper() \
{ \
register_widget(#id, \
std::bind(load_widget_definitions<type>, \
_1, \
_2, \
_3, \
key)); \
register_widget(#id, [](const config& cfg) { return std::make_shared<type>(cfg); }, key); \
\
register_builder_widget( \
#id, \
std::bind( \
build_widget<implementation::builder_##id>, \
_1)); \
register_builder_widget(#id, &build_widget<implementation::builder_##id>); \
} \
}; \
\
@ -63,8 +54,8 @@
/**
* Wrapper for REGISTER_WIDGET3.
*
* "Calls" REGISTER_WIDGET3(id_definition, id, _4)
* "Calls" REGISTER_WIDGET3(id_definition, id, nullptr)
*/
#define REGISTER_WIDGET(id) REGISTER_WIDGET3(id##_definition, id, _4)
#define REGISTER_WIDGET(id) REGISTER_WIDGET3(id##_definition, id, nullptr)
#endif

View file

@ -46,8 +46,8 @@ namespace gui2
// ------------ WIDGET -----------{
REGISTER_WIDGET(listbox)
REGISTER_WIDGET3(listbox_definition, horizontal_listbox, _4)
REGISTER_WIDGET3(listbox_definition, grid_listbox, _4)
REGISTER_WIDGET3(listbox_definition, horizontal_listbox, nullptr)
REGISTER_WIDGET3(listbox_definition, grid_listbox, nullptr)
namespace
{

View file

@ -84,12 +84,13 @@ static std::vector<std::string>& registered_window_types()
return result;
}
typedef std::map<std::string,
std::function<void(gui_definition&,
const std::string&,
const config&,
const char* key)> >
tregistered_widget_type;
struct tregistered_widget_type_mapped_type
{
std::function<styled_widget_definition_ptr(const config&)> parser;
const char* key;
};
typedef std::map<std::string, tregistered_widget_type_mapped_type> tregistered_widget_type;
static tregistered_widget_type& registred_widget_type()
{
@ -350,7 +351,13 @@ const std::string& gui_definition::read(const config& cfg)
for(auto & widget_type : registred_widget_type())
{
widget_type.second(*this, widget_type.first, cfg, nullptr);
std::vector<styled_widget_definition_ptr> definitions;
for (const auto & definition :
cfg.child_range(widget_type.second.key ? widget_type.second.key : widget_type.first + "_definition"))
{
definitions.push_back(widget_type.second.parser(definition));
}
load_widget_definitions(widget_type.first, definitions);
}
/***** Window types *****/
@ -471,7 +478,7 @@ static std::map<std::string, gui_definition> guis;
static std::map<std::string, gui_definition>::const_iterator current_gui = guis.end();
/** Points to the default gui. */
static std::map<std::string, gui_definition>::const_iterator default_gui = guis.end();
static std::map<std::string, gui_definition>::iterator default_gui = guis.end();
void register_window(const std::string& id)
{
@ -570,15 +577,10 @@ state_definition::state_definition(const config& cfg) : canvas_()
canvas_.set_cfg(draw);
}
void register_widget(const std::string& id,
std::function<void(gui_definition& gui,
const std::string& definition_type,
const config& cfg,
const char* key)> functor)
void register_widget(const std::string& id, std::function<styled_widget_definition_ptr(const config&)> f, const char* key)
{
registred_widget_type().insert(std::make_pair(id, functor));
registred_widget_type()[id] = {f, key};
}
void
load_widget_definitions(gui_definition& gui,
const std::string& definition_type,
@ -702,4 +704,31 @@ get_window_builder(const std::string& type)
*
*/
bool add_single_widget_definition(const std::string& widget_type, const std::string& definition_id, const config& cfg)
{
auto& gui = default_gui->second;
auto parser = registred_widget_type().find(widget_type);
if (parser == registred_widget_type().end()) {
throw std::invalid_argument("widget '" + widget_type + "' doesn't exist");
}
if (gui.control_definition[widget_type].find(definition_id) != gui.control_definition[widget_type].end()) {
return false;
}
gui.control_definition[widget_type].insert(std::make_pair(definition_id, parser->second.parser(cfg)));
return true;
}
void remove_single_widget_definition(const std::string& widget_type, const std::string& definition_id)
{
auto& gui = default_gui->second;
auto it = gui.control_definition[widget_type].find(definition_id);
if ( it != gui.control_definition[widget_type].end()) {
gui.control_definition[widget_type].erase(it);
}
}
} // namespace gui2

View file

@ -78,13 +78,10 @@ class unit_test_access_only
* regarding the static initialization problem.
*
* @param id The id of the widget to register.
* @param functor The function to load the definitions.
* @param functor The function to parse the definition config.
* @param key the tagname to read the widgetsdeiniftion from the game config, nullptr means use the default [<id>_definition].
*/
void register_widget(const std::string& id,
std::function<void(gui_definition& gui,
const std::string& definition_type,
const config& cfg,
const char* key)> functor);
void register_widget(const std::string& id, std::function<styled_widget_definition_ptr(const config&)> f, const char* key = nullptr);
/**
* Loads the definitions of a widget.
@ -101,43 +98,15 @@ void load_widget_definitions(
const std::string& definition_type,
const std::vector<styled_widget_definition_ptr>& definitions);
/**
* Loads the definitions of a widget.
*
* This function is templated and kept small so only loads the definitions from
* the config and then lets the real job be done by the @ref
* load_widget_definitions above.
*
* @param gui_definition The gui definition the widget definition
* belongs to.
* @param definition_type The type of the widget whose definitions are
* to be loaded.
* @param cfg The config to serialise the definitions
* from.
* @param key Optional id of the definition to load.
*/
template <class T>
void load_widget_definitions(gui_definition& gui,
const std::string& definition_type,
const config& cfg,
const char* key)
{
std::vector<styled_widget_definition_ptr> definitions;
for (const auto & definition :
cfg.child_range(key ? key : definition_type + "_definition"))
{
definitions.push_back(std::make_shared<T>(definition));
}
load_widget_definitions(gui, definition_type, definitions);
}
resolution_definition_ptr get_control(const std::string& control_type,
const std::string& definition);
bool add_single_widget_definition(const std::string& widget_type, const std::string& definition_id, const config& cfg);
void remove_single_widget_definition(const std::string& widget_type, const std::string& definition_id);
/** Helper struct to signal that get_window_builder failed. */
struct window_builder_invalid_id
{

View file

@ -27,6 +27,7 @@
#include "gui/widgets/multi_page.hpp" // for tmulti_page
#include "gui/widgets/progress_bar.hpp" // for tprogress_bar
#include "gui/widgets/selectable_item.hpp" // for tselectable_item
#include "gui/widgets/settings.hpp"
#include "gui/widgets/slider.hpp" // for tslider
#include "gui/widgets/stacked_widget.hpp"
#include "gui/widgets/text_box.hpp" // for ttext_box
@ -45,6 +46,7 @@
#include "config.hpp"
#include "log.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_kernel_base.hpp"
#include "scripting/lua_unit.hpp"
#include "scripting/lua_unit_type.hpp"
#include "scripting/push_check.hpp"
@ -842,4 +844,24 @@ int intf_add_dialog_tree_node(lua_State *L)
return 0;
}
/**
* - Arg 1: string, widget type
* - Arg 3: string, id
* - Arg 3: conifg,
*/
int intf_add_widget_definition(lua_State *L)
{
std::string type = luaL_checkstring(L, 1);
std::string id = luaL_checkstring(L, 2);
try {
if (gui2::add_single_widget_definition(type, id, luaW_checkconfig(L, 3))) {
lua_kernel_base::get_lua_kernel<lua_kernel_base>(L).add_widget_definition(type, id);
}
}
catch (const std::invalid_argument& e) {
return luaL_argerror(L, 1, e.what());
}
return 0;
}
} // end namespace lua_gui2

View file

@ -33,6 +33,7 @@ int intf_set_dialog_focus(lua_State *L);
int intf_set_dialog_active(lua_State *L);
int intf_set_dialog_visible(lua_State *L);
int intf_add_dialog_tree_node(lua_State *L);
int intf_add_widget_definition(lua_State *L);
int show_dialog(lua_State *L, CVideo & video);
int show_message_dialog(lua_State *L, CVideo & video);
int show_popup_dialog(lua_State *L, CVideo & video);

View file

@ -19,6 +19,7 @@
#include "exceptions.hpp"
#include "game_config.hpp"
#include "game_errors.hpp"
#include "gui/widgets/settings.hpp"
#include "log.hpp"
#include "lua_jailbreak_exception.hpp" // for lua_jailbreak_exception
#include "random_new.hpp"
@ -355,6 +356,7 @@ lua_kernel_base::lua_kernel_base()
{ "set_dialog_active", &lua_gui2::intf_set_dialog_active },
{ "set_dialog_visible", &lua_gui2::intf_set_dialog_visible },
{ "add_dialog_tree_node", &lua_gui2::intf_add_dialog_tree_node },
{ "add_widget_definition", &lua_gui2::intf_add_widget_definition },
{ "set_dialog_callback", &lua_gui2::intf_set_dialog_callback },
{ "set_dialog_canvas", &lua_gui2::intf_set_dialog_canvas },
{ "set_dialog_focus", &lua_gui2::intf_set_dialog_focus },
@ -467,6 +469,9 @@ lua_kernel_base::lua_kernel_base()
lua_kernel_base::~lua_kernel_base()
{
for (const auto& pair : this->registered_widget_definitions_) {
gui2::remove_single_widget_definition(std::get<0>(pair), std::get<1>(pair));
}
lua_close(mState);
}

View file

@ -73,6 +73,7 @@ public:
virtual uint32_t get_random_seed();
lua_State * get_state() { return mState; }
void add_widget_definition(const std::string& type, const std::string& id) { registered_widget_definitions_.emplace_back(type, id); }
protected:
lua_State *mState;
@ -135,6 +136,7 @@ protected:
int intf_require(lua_State * L);
private:
static lua_kernel_base*& get_lua_kernel_base_ptr(lua_State *L);
std::vector<std::tuple<std::string, std::string>> registered_widget_definitions_;
};
#endif