From 0f9440fa61fbfd95b0c06217d08b07c81c897ee0 Mon Sep 17 00:00:00 2001
From: sapier <Sapier at GMX dot net>
Date: Sun, 10 Nov 2013 19:37:45 +0100
Subject: [PATCH] Fix "TODO read modinfo" in modmanager to improve ui usability

---
 builtin/misc_helpers.lua | 56 ++++++++++++++++++++++++++++++
 builtin/modmgr.lua       | 74 +++++++++++++++++++++++++++++++---------
 doc/lua_api.txt          |  8 +++++
 src/guiFormSpecMenu.cpp  |  9 ++++-
 4 files changed, 130 insertions(+), 17 deletions(-)

diff --git a/builtin/misc_helpers.lua b/builtin/misc_helpers.lua
index 38909ec1d..55c5798d7 100644
--- a/builtin/misc_helpers.lua
+++ b/builtin/misc_helpers.lua
@@ -205,6 +205,62 @@ function tbl.formspec_escape(text)
 	return text
 end
 
+
+function tbl.splittext(text,charlimit)
+	local retval = {}
+
+	local current_idx = 1
+	
+	local start,stop = string.find(text," ",current_idx)
+	local nl_start,nl_stop = string.find(text,"\n",current_idx)
+	local gotnewline = false
+	if nl_start ~= nil and (start == nil or nl_start < start) then
+		start = nl_start
+		stop = nl_stop
+		gotnewline = true
+	end
+	local last_line = ""
+	while start ~= nil do
+		if string.len(last_line) + (stop-start) > charlimit then
+			table.insert(retval,last_line)
+			last_line = ""
+		end
+		
+		if last_line ~= "" then
+			last_line = last_line .. " "
+		end
+		
+		last_line = last_line .. string.sub(text,current_idx,stop -1)
+		
+		if gotnewline then
+			table.insert(retval,last_line)
+			last_line = ""
+			gotnewline = false
+		end
+		current_idx = stop+1
+		
+		start,stop = string.find(text," ",current_idx)
+		nl_start,nl_stop = string.find(text,"\n",current_idx)
+	
+		if nl_start ~= nil and (start == nil or nl_start < start) then
+			start = nl_start
+			stop = nl_stop
+			gotnewline = true
+		end
+	end
+	
+	--add last part of text
+	if string.len(last_line) + (string.len(text) - current_idx) > charlimit then
+			table.insert(retval,last_line)
+			table.insert(retval,string.sub(text,current_idx))
+	else
+		last_line = last_line .. " " .. string.sub(text,current_idx)
+		table.insert(retval,last_line)
+	end
+	
+	return retval
+end
+
 --------------------------------------------------------------------------------
 
 if minetest then
diff --git a/builtin/modmgr.lua b/builtin/modmgr.lua
index d9579c652..04f19ec86 100644
--- a/builtin/modmgr.lua
+++ b/builtin/modmgr.lua
@@ -235,13 +235,14 @@ function modmgr.tab()
 	local retval = 
 		"vertlabel[0,-0.25;".. fgettext("MODS") .. "]" ..
 		"label[0.8,-0.25;".. fgettext("Installed Mods:") .. "]" ..
-		"textlist[0.75,0.25;4.5,4.3;modlist;" ..
+		"textlist[0.75,0.25;4.5,4;modlist;" ..
 		modmgr.render_modlist(modmgr.global_mods) .. 
 		";" .. modmgr.selected_mod .. "]"
 
 	retval = retval ..
-		"button[1,4.85;2,0.5;btn_mod_mgr_install_local;".. fgettext("Install") .. "]" ..
-		"button[3,4.85;2,0.5;btn_mod_mgr_download;".. fgettext("Download") .. "]"
+		"label[0.8,4.2;" .. fgettext("Add mod:") .. "]" .. 
+		"button[0.75,4.85;1.8,0.5;btn_mod_mgr_install_local;".. fgettext("Local install") .. "]" ..
+		"button[2.45,4.85;3.05,0.5;btn_mod_mgr_download;".. fgettext("Online mod repository") .. "]"
 		
 	local selected_mod = nil
 		
@@ -250,25 +251,66 @@ function modmgr.tab()
 	end
 	
 	if selected_mod ~= nil then
-		if selected_mod.is_modpack then
-			retval = retval 
-			.. "button[10,4.85;2,0.5;btn_mod_mgr_rename_modpack;" ..
-					 fgettext("Rename") .. "]"
+		local modscreenshot = nil
+		
+		--check for screenshot beeing available
+		local screenshotfilename = selected_mod.path .. DIR_DELIM .. "screenshot.png"
+		local error = nil
+		screenshotfile,error = io.open(screenshotfilename,"r")
+		if error == nil then
+			screenshotfile:close()
+			modscreenshot = screenshotfilename
+		end
+	
+		if modscreenshot == nil then
+				modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
+		end
+		
+		retval = retval 
+				.. "image[5.5,0;3,2;" .. modscreenshot .. "]"
+				.. "label[8.25,0.6;" .. selected_mod.name .. "]"
+				
+		local descriptionlines = nil
+		error = nil
+		local descriptionfilename = selected_mod.path .. "description.txt"
+		descriptionfile,error = io.open(descriptionfilename,"r")
+		if error == nil then
+			descriptiontext = descriptionfile:read("*all")
+			
+			descriptionlines = engine.splittext(descriptiontext,42)
+			descriptionfile:close()
 		else
-		--show dependencies
-			retval = retval .. 
-				"label[6,1.9;".. fgettext("Depends:") .. "]" ..
-				"textlist[6,2.4;5.7,2;deplist;"
+			descriptionlines = {}
+			table.insert(descriptionlines,fgettext("No mod description available"))
+		end
+	
+		retval = retval .. 
+			"label[5.5,1.7;".. fgettext("Mod information:") .. "]" ..
+			"textlist[5.5,2.2;6.2,2.4;description;"
+			
+		for i=1,#descriptionlines,1 do
+			retval = retval .. engine.formspec_escape(descriptionlines[i]) .. ","
+		end
+		
+		
+		if selected_mod.is_modpack then
+			retval = retval .. ";0]" .. 
+				"button[10,4.85;2,0.5;btn_mod_mgr_rename_modpack;" ..
+				fgettext("Rename") .. "]"
+			retval = retval .. "button[5.5,4.85;4.5,0.5;btn_mod_mgr_delete_mod;"
+				.. fgettext("Uninstall selected modpack") .. "]"
+		else
+			--show dependencies
+
+			retval = retval .. ",Depends:,"
 				
 			toadd = modmgr.get_dependencies(selected_mod.path)
 			
-			retval = retval .. toadd .. ";0;true,false]"
+			retval = retval .. toadd .. ";0]"
 			
-			--TODO read modinfo
+			retval = retval .. "button[5.5,4.85;4.5,0.5;btn_mod_mgr_delete_mod;"
+				.. fgettext("Uninstall selected mod") .. "]"
 		end
-		--show delete button
-		retval = retval .. "button[8,4.85;2,0.5;btn_mod_mgr_delete_mod;"
-				.. fgettext("Delete") .. "]"
 	end
 	return retval
 end
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index c4d12db0f..db9a5e8fa 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -100,6 +100,8 @@ Mod directory structure
 mods
 |-- modname
 |   |-- depends.txt
+|   |-- screenshot.png
+|   |-- description.txt
 |   |-- init.lua
 |   |-- textures
 |   |   |-- modname_stuff.png
@@ -121,6 +123,12 @@ depends.txt:
   to a single modname. Their meaning is that if the specified mod
   is missing, that does not prevent this mod from being loaded.
 
+screenshot.png:
+  A screenshot shown in modmanager within mainmenu.
+
+description.txt:
+  File containing desctiption to be shown within mainmenu.
+
 optdepends.txt:
   An alternative way of specifying optional dependencies.
   Like depends.txt, a single line contains a single modname.
diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index e0ef55acd..aa1e2d9c9 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -721,8 +721,15 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) {
 				scrollbar->setPos(data->listbox_scroll[fname_w]);
 			}
 		}
+		else {
+			gui::IGUIScrollBar *scrollbar = getListboxScrollbar(e);
+			if (scrollbar) {
+				scrollbar->setPos(0);
+			}
+		}
 
-		if (str_initial_selection != "")
+		if ((str_initial_selection != "") &&
+				(str_initial_selection != "0"))
 			e->setSelected(stoi(str_initial_selection.c_str())-1);
 
 		m_listboxes.push_back(std::pair<FieldSpec,gui::IGUIListBox*>(spec,e));