Merge pull request #436 from doserj/mod_selection

Fix some crashes and improved behaviour for mod selection gui
master
celeron55 2013-01-23 10:10:25 -08:00
commit 0a27e81704
5 changed files with 51 additions and 27 deletions

View File

@ -69,15 +69,13 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
m_worldmods = flattenModTree(getModsInPath(worldmods_path)); m_worldmods = flattenModTree(getModsInPath(worldmods_path));
// fill m_addontree with add-on mods // fill m_addontree with add-on mods
ModSpec addons("Add-Ons");
std::set<std::string> paths = m_gspec.addon_mods_paths; std::set<std::string> paths = m_gspec.addon_mods_paths;
for(std::set<std::string>::iterator it=paths.begin(); for(std::set<std::string>::iterator it=paths.begin();
it != paths.end(); ++it) it != paths.end(); ++it)
{ {
std::map<std::string,ModSpec> mods = getModsInPath(*it); std::map<std::string,ModSpec> mods = getModsInPath(*it);
addons.modpack_content.insert(mods.begin(), mods.end()); m_addontree.insert(mods.begin(), mods.end());
} }
m_addontree.insert(std::make_pair(addons.name,addons));
// expand modpacks // expand modpacks
m_addonmods = flattenModTree(m_addontree); m_addonmods = flattenModTree(m_addontree);
@ -116,7 +114,7 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
ModSpec mod = (*it).second; ModSpec mod = (*it).second;
// a mod is new if it is not a modpack, and does not occur in // a mod is new if it is not a modpack, and does not occur in
// mod_names // mod_names
if(mod.modpack_content.empty() && if(!mod.is_modpack &&
mod_names.count(modname) == 0) mod_names.count(modname) == 0)
m_new_mod_names.insert(modname); m_new_mod_names.insert(modname);
} }
@ -253,7 +251,9 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize)
rect += v2s32(220, 0) + topleft; rect += v2s32(220, 0) + topleft;
m_treeview = Environment->addTreeView(rect, this, m_treeview = Environment->addTreeView(rect, this,
GUI_ID_MOD_TREEVIEW,true); GUI_ID_MOD_TREEVIEW,true);
buildTreeView(m_addontree, m_treeview->getRoot()); gui::IGUITreeViewNode* node
= m_treeview->getRoot()->addChildBack(L"Add-Ons");
buildTreeView(m_addontree, node);
} }
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
@ -407,8 +407,12 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
return true; return true;
} }
case GUI_ID_ENABLEALL: { case GUI_ID_ENABLEALL: {
if(selected_node != NULL && selected_node->getText() != NULL) if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot())
{ {
enableAllMods(m_addonmods,true);
}
else if(selected_node != NULL && selected_node->getText() != NULL)
{
std::string modname = wide_to_narrow(selected_node->getText()); std::string modname = wide_to_narrow(selected_node->getText());
ModSpec mod = m_addonmods[modname]; ModSpec mod = m_addonmods[modname];
enableAllMods(mod.modpack_content,true); enableAllMods(mod.modpack_content,true);
@ -416,6 +420,10 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
return true; return true;
} }
case GUI_ID_DISABLEALL: { case GUI_ID_DISABLEALL: {
if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot())
{
enableAllMods(m_addonmods,false);
}
if(selected_node != NULL && selected_node->getText() != NULL) if(selected_node != NULL && selected_node->getText() != NULL)
{ {
std::string modname = wide_to_narrow(selected_node->getText()); std::string modname = wide_to_narrow(selected_node->getText());
@ -517,7 +525,7 @@ void GUIConfigureWorld::buildTreeView(std::map<std::string, ModSpec> mods,
gui::IGUITreeViewNode* new_node = gui::IGUITreeViewNode* new_node =
node->addChildBack(narrow_to_wide(modname).c_str()); node->addChildBack(narrow_to_wide(modname).c_str());
m_nodes.insert(std::make_pair(modname, new_node)); m_nodes.insert(std::make_pair(modname, new_node));
if(!mod.modpack_content.empty()) if(mod.is_modpack)
buildTreeView(mod.modpack_content, new_node); buildTreeView(mod.modpack_content, new_node);
else else
{ {
@ -552,23 +560,33 @@ void GUIConfigureWorld::adjustSidebar()
modname_w = L"N/A"; modname_w = L"N/A";
std::string modname = wide_to_narrow(modname_w); std::string modname = wide_to_narrow(modname_w);
// if modpack, show enable/disable all buttons. otherwise, show // if no mods installed, don't show buttons or checkbox on the sidebar
// enabled checkbox if(node->getParent() == m_treeview->getRoot() && !node->hasChilds())
if(node->hasChilds())
{
m_enabled_checkbox->setVisible(false);
m_disableall->setVisible(true);
m_enableall->setVisible(true);
m_modname_text->setText((L"Modpack: "+modname_w).c_str());
}
else
{ {
m_disableall->setVisible(false); m_disableall->setVisible(false);
m_enableall->setVisible(false); m_enableall->setVisible(false);
m_enabled_checkbox->setVisible(true); m_enabled_checkbox->setVisible(false);
m_modname_text->setText((L"Mod: "+modname_w).c_str()); }
else
{
// if modpack, show enable/disable all buttons. otherwise, show
// enabled checkbox
if(node->getParent() == m_treeview->getRoot() ||
m_addonmods[modname].is_modpack)
{
m_enabled_checkbox->setVisible(false);
m_disableall->setVisible(true);
m_enableall->setVisible(true);
m_modname_text->setText((L"Modpack: "+modname_w).c_str());
}
else
{
m_disableall->setVisible(false);
m_enableall->setVisible(false);
m_enabled_checkbox->setVisible(true);
m_modname_text->setText((L"Mod: "+modname_w).c_str());
}
} }
// the mod is enabled unless it is disabled in the world.mt settings. // the mod is enabled unless it is disabled in the world.mt settings.
bool mod_enabled = true; bool mod_enabled = true;
if(m_settings.exists("load_mod_"+modname)) if(m_settings.exists("load_mod_"+modname))
@ -616,7 +634,7 @@ void GUIConfigureWorld::enableAllMods(std::map<std::string, ModSpec> mods,bool e
it != mods.end(); ++it) it != mods.end(); ++it)
{ {
ModSpec mod = (*it).second; ModSpec mod = (*it).second;
if(!mod.modpack_content.empty()) if(mod.is_modpack)
// a modpack, recursively enable all mods in it // a modpack, recursively enable all mods in it
enableAllMods(mod.modpack_content,enable); enableAllMods(mod.modpack_content,enable);
else // not a modpack else // not a modpack

View File

@ -1048,12 +1048,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent, GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent,
-1, menumgr, wspec); -1, menumgr, wspec);
menu->drop(); menu->drop();
return true;
} }
return true;
} }
case GUI_ID_SERVERLIST_DELETE: { case GUI_ID_SERVERLIST_DELETE: {
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST); gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
u16 selected = ((gui::IGUIListBox*)serverlist)->getSelected(); s32 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
if (selected == -1) return true; if (selected == -1) return true;
ServerList::deleteEntry(m_data->servers[selected]); ServerList::deleteEntry(m_data->servers[selected]);
m_data->servers = ServerList::getLocal(); m_data->servers = ServerList::getLocal();

View File

@ -46,6 +46,7 @@ std::map<std::string, ModSpec> getModsInPath(std::string path)
modpack_is.close(); // We don't actually need the file modpack_is.close(); // We don't actually need the file
ModSpec spec(modname,modpath); ModSpec spec(modname,modpath);
spec.modpack_content = getModsInPath(modpath); spec.modpack_content = getModsInPath(modpath);
spec.is_modpack = true;
result.insert(std::make_pair(modname,spec)); result.insert(std::make_pair(modname,spec));
} }
else // not a modpack, add the modspec else // not a modpack, add the modspec
@ -76,7 +77,7 @@ std::map<std::string, ModSpec> flattenModTree(std::map<std::string, ModSpec> mod
it != mods.end(); ++it) it != mods.end(); ++it)
{ {
ModSpec mod = (*it).second; ModSpec mod = (*it).second;
if(!mod.modpack_content.empty()) //is a modpack if(mod.is_modpack)
{ {
std::map<std::string, ModSpec> content = std::map<std::string, ModSpec> content =
flattenModTree(mod.modpack_content); flattenModTree(mod.modpack_content);
@ -98,7 +99,7 @@ std::vector<ModSpec> flattenMods(std::map<std::string, ModSpec> mods)
it != mods.end(); ++it) it != mods.end(); ++it)
{ {
ModSpec mod = (*it).second; ModSpec mod = (*it).second;
if(!mod.modpack_content.empty()) //is a modpack if(mod.is_modpack)
{ {
std::vector<ModSpec> content = flattenMods(mod.modpack_content); std::vector<ModSpec> content = flattenMods(mod.modpack_content);
result.reserve(result.size() + content.size()); result.reserve(result.size() + content.size());

View File

@ -53,6 +53,8 @@ struct ModSpec
//if normal mod: //if normal mod:
std::set<std::string> depends; std::set<std::string> depends;
std::set<std::string> unsatisfied_depends; std::set<std::string> unsatisfied_depends;
bool is_modpack;
// if modpack: // if modpack:
std::map<std::string,ModSpec> modpack_content; std::map<std::string,ModSpec> modpack_content;
ModSpec(const std::string name_="", const std::string path_="", ModSpec(const std::string name_="", const std::string path_="",
@ -61,6 +63,7 @@ struct ModSpec
path(path_), path(path_),
depends(depends_), depends(depends_),
unsatisfied_depends(depends_), unsatisfied_depends(depends_),
is_modpack(false),
modpack_content() modpack_content()
{} {}
}; };

View File

@ -244,7 +244,9 @@ public:
updated[name] = true; updated[name] = true;
} }
else //file contains a setting which is not in m_settings
value_changed=true;
return true; return true;
} }