static void do_resolve_rects(const config& cfg, config& resolved_config, config* resol_cfg = NULL) { // recursively resolve children for(config::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++i) { const config::all_children_iterator::value_type& value = *i; config& childcfg = resolved_config.add_child(value.first); do_resolve_rects(*value.second, childcfg, (value.first == "resolution") ? &childcfg : resol_cfg); } // copy all key/values for(string_map::const_iterator j = cfg.values.begin(); j != cfg.values.end(); ++j) { resolved_config.values[j->first] = j->second; } // override default reference rect with "ref" parameter if any if (!cfg["ref"].empty()) { if (resol_cfg == NULL) { ERR_DP << "Use of ref= outside a [resolution] block\n"; } else { //DBG_DP << ">> Looking for " << cfg["ref"] << "\n"; const config ref = find_ref (cfg["ref"], *resol_cfg); if (ref["id"].empty()) { ERR_DP << "Reference to non-existent rect id \"" << cfg["ref"] << "\"\n"; } else if (ref["rect"].empty()) { ERR_DP << "Reference to id \"" << cfg["ref"] << "\" which does not have a \"rect\"\n"; } else { ref_rect = read_rect(ref); } } } // resolve the rect value to absolute coordinates if (!cfg["rect"].empty()) { resolved_config.values["rect"] = resolve_rect(cfg["rect"]); } }
tbuilder_widget_ptr create_builder_widget(const config& cfg) { config::const_all_children_itors children = cfg.all_children_range(); VALIDATE(children.size() == 1, "Grid cell does not have exactly 1 child."); for(const auto & item : builder_widget_lookup()) { if(item.first == "window" || item.first == "tooltip") { continue; } if(const config& c = cfg.child(item.first)) { return item.second(c); } } if(const config& c = cfg.child("grid")) { return std::make_shared<tbuilder_grid>(c); } if(const config& instance = cfg.child("instance")) { return std::make_shared<implementation::tbuilder_instance>(instance); } if(const config& pane = cfg.child("pane")) { return std::make_shared<implementation::tbuilder_pane>(pane); } if(const config& viewport = cfg.child("viewport")) { return std::make_shared<implementation::tbuilder_viewport>(viewport); } /* * This is rather odd, when commented out the classes no longer seem to be in * the executable, no real idea why, except maybe of an overzealous optimizer * while linking. It seems that all these classes aren't explicitly * instantiated but only implicitly. Also when looking at the symbols in * libwesnoth-game.a the repeating button is there regardless of this #if but * in the final binary only if the #if is enabled. * * If this code is executed, which it will cause an assertion failure. * * Its likeley that this happens becasue some build this as a library file * which is then used by the wesnoth executable. For msvc a good try to fix * this issue is to add __pragma(comment(linker, "/include:" #TYPE)) or * similar in the REGISTER_WIDGET3 macro. For gcc and similar this can only * be fixed by using --whole-archive flag when linking this library. */ #if 1 #define TRY(name) \ do { \ if(const config& c = cfg.child(#name)) { \ tbuilder_widget_ptr p = \ std::make_shared<implementation::tbuilder_##name>(c); \ assert(false); \ } \ } while(0) TRY(stacked_widget); TRY(scrollbar_panel); TRY(horizontal_scrollbar); TRY(repeating_button); TRY(vertical_scrollbar); TRY(label); TRY(image); TRY(toggle_button); TRY(slider); TRY(scroll_label); TRY(matrix); TRY(minimap); TRY(button); TRY(menu_button); TRY(drawing); TRY(password_box); TRY(unit_preview_pane); #undef TRY #endif // FAIL() doesn't return FAIL("Unknown widget type " + cfg.ordered_begin()->key); }