Browse Source

Improve the path select GUI (#5852)

- Allow lua to chose whatever directories or files can be selected
- Fix selecting directories
- Rename dialog to `guiPathSelectMenu` from `guiFileSelectMenu`
- Rename lua function for opening the menu from `show_file_open_dialog` to `show_path_select_dialog`
- Remove duplicate code and fix code style.

Related changes
- fix `clang-format` whitelist.
- Regenerate minetest.conf.example
red-001 7 years ago
parent
commit
26e2eb019a

+ 1 - 1
build/android/jni/Android.mk

@@ -152,7 +152,7 @@ LOCAL_SRC_FILES := \
 		jni/src/gettext.cpp                       \
 		jni/src/guiChatConsole.cpp                \
 		jni/src/guiEngine.cpp                     \
-		jni/src/guiFileSelectMenu.cpp             \
+		jni/src/guiPathSelectMenu.cpp             \
 		jni/src/guiFormSpecMenu.cpp               \
 		jni/src/guiKeyChangeMenu.cpp              \
 		jni/src/guiPasswordChange.cpp             \

+ 11 - 5
builtin/mainmenu/dlg_settings_advanced.lua

@@ -196,7 +196,7 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se
 		return
 	end
 
-	if setting_type == "path" then
+	if setting_type == "path" or setting_type == "filepath" then
 		local default = remaining_line:match("^(.*)$")
 
 		if not default then
@@ -206,7 +206,7 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se
 		table.insert(settings, {
 			name = name,
 			readable_name = readable_name,
-			type = "path",
+			type = setting_type,
 			default = default,
 			comment = current_comment,
 		})
@@ -504,14 +504,14 @@ local function create_change_setting_formspec(dialogdata)
 		end
 		formspec = formspec .. ";" .. selected_index .. "]"
 
-	elseif setting.type == "path" then
+	elseif setting.type == "path" or setting.type == "filepath" then
 		local current_value = dialogdata.selected_path
 		if not current_value then
 			current_value = get_current_value(setting)
 		end
 		formspec = formspec .. "field[0.5,4;7.5,1;te_setting_value;;"
 				.. core.formspec_escape(current_value) .. "]"
-				.. "button[8,3.75;2,1;btn_browser_path;" .. fgettext("Browse") .. "]"
+				.. "button[8,3.75;2,1;btn_browser_" .. setting.type .. ";" .. fgettext("Browse") .. "]"
 
 	else
 		-- TODO: fancy input for float, int, flags, noise_params, v3f
@@ -606,7 +606,13 @@ local function handle_change_setting_buttons(this, fields)
 	end
 
 	if fields["btn_browser_path"] then
-		core.show_file_open_dialog("dlg_browse_path", fgettext_ne("Select path"))
+		core.show_path_select_dialog("dlg_browse_path",
+			fgettext_ne("Select directory"), false)
+	end
+
+	if fields["btn_browser_filepath"] then
+		core.show_path_select_dialog("dlg_browse_path",
+			fgettext_ne("Select file"), true)
 	end
 
 	if fields["dlg_browse_path_accepted"] then

+ 6 - 3
builtin/settingtypes.txt

@@ -12,6 +12,7 @@
 #    - float
 #    - enum
 #    - path
+#    - filepath
 #    - key (will be ignored in GUI, since a special key change dialog exists)
 #    - flags
 #    - noise_params
@@ -31,6 +32,8 @@
 #            - default value1,value2,...
 #   * path:
 #            - default (if default is not specified then "" is set)
+#   * filepath:
+#            - default (if default is not specified then "" is set)
 #   * key:
 #            - default
 #   * flags:
@@ -642,7 +645,7 @@ tooltip_show_delay (Tooltip delay) int 400
 freetype (Freetype fonts) bool true
 
 #    Path to TrueTypeFont or bitmap.
-font_path (Font path) path fonts/liberationsans.ttf
+font_path (Font path) filepath fonts/liberationsans.ttf
 
 font_size (Font size) int 16
 
@@ -652,12 +655,12 @@ font_shadow (Font shadow) int 1
 #    Font shadow alpha (opaqueness, between 0 and 255).
 font_shadow_alpha (Font shadow alpha) int 127 0 255
 
-mono_font_path (Monospace font path) path fonts/liberationmono.ttf
+mono_font_path (Monospace font path) filepath fonts/liberationmono.ttf
 
 mono_font_size (Monospace font size) int 15
 
 #    This font will be used for certain languages.
-fallback_font_path (Fallback font) path fonts/DroidSansFallbackFull.ttf
+fallback_font_path (Fallback font) filepath fonts/DroidSansFallbackFull.ttf
 fallback_font_size (Fallback font size) int 15
 fallback_font_shadow (Fallback font shadow) int 1
 fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255

+ 3 - 3
minetest.conf.example

@@ -757,7 +757,7 @@
 # freetype = true
 
 #    Path to TrueTypeFont or bitmap.
-#    type: path
+#    type: filepath
 # font_path = fonts/liberationsans.ttf
 
 #    type: int
@@ -771,14 +771,14 @@
 #    type: int min: 0 max: 255
 # font_shadow_alpha = 127
 
-#    type: path
+#    type: filepath
 # mono_font_path = fonts/liberationmono.ttf
 
 #    type: int
 # mono_font_size = 15
 
 #    This font will be used for certain languages.
-#    type: path
+#    type: filepath
 # fallback_font_path = fonts/DroidSansFallbackFull.ttf
 
 #    type: int

+ 1 - 1
src/CMakeLists.txt

@@ -509,7 +509,7 @@ set(client_SRCS
 	game.cpp
 	guiChatConsole.cpp
 	guiEngine.cpp
-	guiFileSelectMenu.cpp
+	guiPathSelectMenu.cpp
 	guiFormSpecMenu.cpp
 	guiKeyChangeMenu.cpp
 	guiPasswordChange.cpp

+ 44 - 48
src/guiFileSelectMenu.cpp → src/guiPathSelectMenu.cpp

@@ -17,16 +17,18 @@
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "guiFileSelectMenu.h"
+#include "guiPathSelectMenu.h"
 
 GUIFileSelectMenu::GUIFileSelectMenu(gui::IGUIEnvironment* env,
 		gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
-		const std::string &title, const std::string &formname) :
+		const std::string &title, const std::string &formname,
+		bool is_file_select) :
 	GUIModalMenu(env, parent, id, menumgr),
 	m_title(utf8_to_wide(title)),
 	m_accepted(false),
 	m_text_dst(NULL),
-	m_formname(formname)
+	m_formname(formname),
+	m_file_select_dialog(is_file_select)
 {
 }
 
@@ -36,83 +38,77 @@ GUIFileSelectMenu::~GUIFileSelectMenu()
 	setlocale(LC_NUMERIC, "C");
 }
 
-void GUIFileSelectMenu::removeChildren()
-{
-	const core::list<gui::IGUIElement*> &children = getChildren();
-	core::list<gui::IGUIElement*> children_copy;
-	for (core::list<gui::IGUIElement*>::ConstIterator i = children.begin(); i
-		 != children.end(); i++)
-	{
-		children_copy.push_back(*i);
-	}
-	for (core::list<gui::IGUIElement*>::Iterator i = children_copy.begin(); i
-		 != children_copy.end(); i++)
-	{
-		(*i)->remove();
-	}
-}
-
 void GUIFileSelectMenu::regenerateGui(v2u32 screensize)
 {
 	removeChildren();
 	m_fileOpenDialog = 0;
 
-	core::dimension2du size(600,400);
-	core::rect < s32 > rect(0,0,screensize.X,screensize.Y);
+	core::dimension2du size(600, 400);
+	core::rect<s32> rect(0, 0, screensize.X, screensize.Y);
 
 	DesiredRect = rect;
 	recalculateAbsolutePosition(false);
 
 	m_fileOpenDialog =
-			Environment->addFileOpenDialog(m_title.c_str(),false,this,-1);
+			Environment->addFileOpenDialog(m_title.c_str(), false, this, -1);
 
-	core::position2di pos = core::position2di(screensize.X/2 - size.Width/2,screensize.Y/2 -size.Height/2);
+	core::position2di pos = core::position2di(screensize.X / 2 - size.Width / 2,
+			screensize.Y / 2 - size.Height / 2);
 	m_fileOpenDialog->setRelativePosition(pos);
 	m_fileOpenDialog->setMinSize(size);
 }
 
 void GUIFileSelectMenu::drawMenu()
 {
-	gui::IGUISkin* skin = Environment->getSkin();
+	gui::IGUISkin *skin = Environment->getSkin();
 	if (!skin)
 		return;
 
 	gui::IGUIElement::draw();
 }
 
-void GUIFileSelectMenu::acceptInput() {
-	if ((m_text_dst != 0) && (this->m_formname != "")){
+void GUIFileSelectMenu::acceptInput()
+{
+	if ((m_text_dst != 0) && (this->m_formname != "")) {
 		StringMap fields;
-
-		if (m_accepted)
-			fields[m_formname + "_accepted"] = wide_to_utf8(m_fileOpenDialog->getFileName());
-		else
+		if (m_accepted) {
+			std::string path;
+			if (!m_file_select_dialog) {
+				core::string<fschar_t> string =
+						m_fileOpenDialog->getDirectoryName();
+				path = std::string(string.c_str());
+			} else {
+				path = wide_to_utf8(m_fileOpenDialog->getFileName());
+			}
+			fields[m_formname + "_accepted"] = path;
+		} else {
 			fields[m_formname + "_canceled"] = m_formname;
-
+		}
 		this->m_text_dst->gotText(fields);
 	}
+	quitMenu();
 }
 
-bool GUIFileSelectMenu::OnEvent(const SEvent& event)
+bool GUIFileSelectMenu::OnEvent(const SEvent &event)
 {
-
 	if (event.EventType == irr::EET_GUI_EVENT) {
 		switch (event.GUIEvent.EventType) {
-			case gui::EGET_ELEMENT_CLOSED:
-			case gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED:
-				m_accepted=false;
-				acceptInput();
-				quitMenu();
-				return true;
-			case gui::EGET_DIRECTORY_SELECTED:
-			case gui::EGET_FILE_SELECTED:
-				m_accepted=true;
-				acceptInput();
-				quitMenu();
-				return true;
-			default:
-				//ignore this event
-				break;
+		case gui::EGET_ELEMENT_CLOSED:
+		case gui::EGET_FILE_CHOOSE_DIALOG_CANCELLED:
+			m_accepted = false;
+			acceptInput();
+			return true;
+		case gui::EGET_DIRECTORY_SELECTED:
+			m_accepted = !m_file_select_dialog;
+			acceptInput();
+			return true;
+		case gui::EGET_FILE_SELECTED:
+			m_accepted = m_file_select_dialog;
+			acceptInput();
+			return true;
+		default:
+			// ignore this event
+			break;
 		}
 	}
 	return Parent ? Parent->OnEvent(event) : false;

+ 2 - 3
src/guiFileSelectMenu.h → src/guiPathSelectMenu.h

@@ -31,11 +31,9 @@ class GUIFileSelectMenu : public GUIModalMenu
 public:
 	GUIFileSelectMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
 			IMenuManager *menumgr, const std::string &title,
-			const std::string &formid);
+			const std::string &formid, bool is_file_select);
 	~GUIFileSelectMenu();
 
-	void removeChildren();
-
 	/*
 	 Remove and re-add (or reposition) stuff
 	 */
@@ -58,6 +56,7 @@ private:
 	TextDest *m_text_dst;
 
 	std::string m_formname;
+	bool m_file_select_dialog;
 };
 
 #endif /* GUIFILESELECTMENU_H_ */

+ 6 - 4
src/script/lua_api/l_mainmenu.cpp

@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "guiEngine.h"
 #include "guiMainMenu.h"
 #include "guiKeyChangeMenu.h"
-#include "guiFileSelectMenu.h"
+#include "guiPathSelectMenu.h"
 #include "subgame.h"
 #include "version.h"
 #include "porting.h"
@@ -950,13 +950,14 @@ bool ModApiMainMenu::isMinetestPath(std::string path)
 }
 
 /******************************************************************************/
-int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
+int ModApiMainMenu::l_show_path_select_dialog(lua_State *L)
 {
 	GUIEngine* engine = getGuiEngine(L);
 	sanity_check(engine != NULL);
 
 	const char *formname= luaL_checkstring(L, 1);
 	const char *title	= luaL_checkstring(L, 2);
+	bool is_file_select = lua_toboolean(L, 3);
 
 	GUIFileSelectMenu* fileOpenMenu =
 		new GUIFileSelectMenu(engine->m_device->getGUIEnvironment(),
@@ -964,7 +965,8 @@ int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
 								-1,
 								engine->m_menumanager,
 								title,
-								formname);
+								formname,
+								is_file_select);
 	fileOpenMenu->setTextDest(engine->m_buttonhandler);
 	fileOpenMenu->drop();
 	return 0;
@@ -1138,7 +1140,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
 	API_FCT(copy_dir);
 	API_FCT(extract_zip);
 	API_FCT(get_mainmenu_path);
-	API_FCT(show_file_open_dialog);
+	API_FCT(show_path_select_dialog);
 	API_FCT(download_file);
 	API_FCT(get_modstore_details);
 	API_FCT(get_modstore_list);

+ 1 - 1
src/script/lua_api/l_mainmenu.h

@@ -86,7 +86,7 @@ private:
 
 	static int l_show_keys_menu(lua_State *L);
 
-	static int l_show_file_open_dialog(lua_State *L);
+	static int l_show_path_select_dialog(lua_State *L);
 
 	static int l_set_topleft_text(lua_State *L);
 

+ 2 - 1
util/travis/clang-format-whitelist.txt

@@ -89,7 +89,8 @@ src/guiChatConsole.cpp
 src/guiChatConsole.h
 src/guiEngine.cpp
 src/guiEngine.h
-src/guiFileSelectMenu.cpp
+src/guiPathSelectMenu.cpp
+src/guiPathSelectMenu.h
 src/guiFormSpecMenu.cpp
 src/guiFormSpecMenu.h
 src/guiKeyChangeMenu.cpp