allow multi_page to contain differnt types of pages

although stacked_widget supports similar functionality this is currently
not easily doable from the lua gui2 api. In particular
1) stacked_widget cannot add pages dynamically
2) multi_page can only contain one type of widget.
3) a stacked_widget inside a multi_page is ineffective since it
generates many unused widgets
4) a multi_page inside a stacked_widget is just unhandy to use
This commit is contained in:
gfgtdf 2017-04-11 15:21:20 +02:00
parent 4908124f6f
commit 75c21815f6
4 changed files with 54 additions and 28 deletions

View file

@ -1892,7 +1892,7 @@
[tag]
name="page_definition"
min="0"
max="1"
max="-1"
super="gui/window/resolution/grid"
[/tag]
[key]

View file

@ -35,25 +35,42 @@ multi_page::multi_page()
: container_base(0)
, generator_(
generator_base::build(true, true, generator_base::independent, false))
, page_builder_(nullptr)
, page_builders_()
{
}
grid& multi_page::add_page(const string_map& item)
{
assert(generator_);
grid& page = generator_->create_item(-1, page_builder_, item, nullptr);
grid& page = generator_->create_item(-1, page_builders_.begin()->second, item, nullptr);
return page;
}
grid& multi_page::add_page(const std::string& type, int insert_pos, const string_map& item)
{
assert(generator_);
auto it_builder = page_builders_.find(type);
VALIDATE(it_builder != page_builders_.end(), "invalid page type '" + type + "'");
return generator_->create_item(insert_pos, it_builder->second, item, nullptr);
}
grid& multi_page::add_page(
const std::map<std::string /* widget id */, string_map>& data)
{
assert(generator_);
grid& page = generator_->create_item(-1, page_builders_.begin()->second, data, nullptr);
return page;
}
grid& multi_page::add_page(
const std::map<std::string /* widget id */, string_map>& data)
const std::string& type, int insert_pos, const std::map<std::string /* widget id */, string_map>& data)
{
assert(generator_);
grid& page = generator_->create_item(-1, page_builder_, data, nullptr);
return page;
auto it_builder = page_builders_.find(type);
VALIDATE(it_builder != page_builders_.end(), "invalid page type '" + type + "'");
return generator_->create_item(insert_pos, it_builder->second, data, nullptr);
}
void multi_page::remove_page(const unsigned page, unsigned count)
@ -158,7 +175,7 @@ void swap_grid(grid* g,
void multi_page::finalize(const std::vector<string_map>& page_data)
{
assert(generator_);
generator_->create_items(-1, page_builder_, page_data, nullptr);
generator_->create_items(-1, page_builders_.begin()->second, page_data, nullptr);
swap_grid(nullptr, &get_grid(), generator_, "_content_grid");
}
@ -271,13 +288,15 @@ namespace implementation
{
builder_multi_page::builder_multi_page(const config& cfg)
: implementation::builder_styled_widget(cfg), builder(nullptr), data()
: implementation::builder_styled_widget(cfg), builders(), data()
{
const config& page = cfg.child("page_definition");
VALIDATE(page, _("No page defined."));
builder = std::make_shared<builder_grid>(page);
assert(builder);
for (const config& page : cfg.child_range("page_definition"))
{
auto builder = std::make_shared<builder_grid>(page);
assert(builder);
builders[page["id"]] = builder;
}
VALIDATE(!builders.empty(), _("No page defined."));
/** @todo This part is untested. */
const config& d = cfg.child("page_data");
@ -285,6 +304,7 @@ builder_multi_page::builder_multi_page(const config& cfg)
return;
}
auto builder = builders.begin()->second;
for(const auto & row : d.child_range("row"))
{
unsigned col = 0;
@ -311,7 +331,7 @@ widget* builder_multi_page::build() const
init_control(widget);
widget->set_page_builder(builder);
widget->set_page_builders(builders);
DBG_GUI_G << "Window builder: placed multi_page '" << id
<< "' with definition '" << definition << "'.\n";

View file

@ -55,6 +55,7 @@ public:
* @returns The grid of the newly added page.
*/
grid& add_page(const string_map& item);
grid& add_page(const std::string& type, int insert_pos, const string_map& item);
/**
* Adds single page to the grid.
@ -74,6 +75,7 @@ public:
* @returns The grid of the newly added page.
*/
grid& add_page(const std::map<std::string /* widget id */, string_map>& data);
grid& add_page(const std::string& type, int insert_pos, const std::map<std::string /* widget id */, string_map>& data);
/**
* Removes a page in the multi page.
@ -137,9 +139,10 @@ public:
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_page_builder(builder_grid_ptr page_builder)
void set_page_builders(const std::map<std::string, builder_grid_const_ptr>& page_builders)
{
page_builder_ = page_builder;
assert(!page_builders.empty());
page_builders_ = page_builders;
}
private:
@ -160,7 +163,7 @@ private:
generator_base* generator_;
/** Contains the builder for the new items. */
builder_grid_const_ptr page_builder_;
std::map<std::string, builder_grid_const_ptr> page_builders_;
/** See @ref widget::impl_draw_background. */
virtual void impl_draw_background(surface& frame_buffer,
@ -201,7 +204,7 @@ struct builder_multi_page : public builder_styled_widget
widget* build() const;
builder_grid_ptr builder;
std::map<std::string, builder_grid_const_ptr> builders;
/**
* Multi page data.

View file

@ -840,16 +840,19 @@ int intf_add_dialog_tree_node(lua_State *L)
const int insert_pos = luaL_checkinteger(L, 2);
static const std::map<std::string, string_map> data;
gui2::widget *w = find_widget(L, 3, false);
gui2::tree_view_node *twn = dynamic_cast<gui2::tree_view_node *>(w);
if (!twn) {
if(gui2::tree_view* tw = dynamic_cast<gui2::tree_view *>(w)) {
twn = &tw->get_root_node();
}
else {
return luaL_argerror(L, lua_gettop(L), "unsupported widget");
}
if (gui2::tree_view_node *twn = dynamic_cast<gui2::tree_view_node *>(w)) {
twn->add_child(node_type, data, insert_pos);
}
else if (gui2::tree_view* tw = dynamic_cast<gui2::tree_view *>(w)) {
tw->get_root_node().add_child(node_type, data, insert_pos);
}
else if (gui2::multi_page *mp = dynamic_cast<gui2::multi_page *>(w)) {
mp->add_page(node_type, insert_pos, data);
}
else {
return luaL_argerror(L, lua_gettop(L), "unsupported widget");
}
twn->add_child(node_type, data, insert_pos);
return 0;
}