From 26e2eb019afa60c66c4dc89cf24bbf5b25c6a383 Mon Sep 17 00:00:00 2001 From: red-001 Date: Sun, 11 Jun 2017 08:43:31 +0100 Subject: 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 --- build/android/jni/Android.mk | 2 +- builtin/mainmenu/dlg_settings_advanced.lua | 16 ++-- builtin/settingtypes.txt | 9 ++- minetest.conf.example | 6 +- src/CMakeLists.txt | 2 +- src/guiFileSelectMenu.cpp | 119 ----------------------------- src/guiFileSelectMenu.h | 63 --------------- src/guiPathSelectMenu.cpp | 115 ++++++++++++++++++++++++++++ src/guiPathSelectMenu.h | 62 +++++++++++++++ src/script/lua_api/l_mainmenu.cpp | 10 ++- src/script/lua_api/l_mainmenu.h | 2 +- util/travis/clang-format-whitelist.txt | 3 +- 12 files changed, 208 insertions(+), 201 deletions(-) delete mode 100644 src/guiFileSelectMenu.cpp delete mode 100644 src/guiFileSelectMenu.h create mode 100644 src/guiPathSelectMenu.cpp create mode 100644 src/guiPathSelectMenu.h diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 7b741e04b..8f3b342c5 100644 --- a/build/android/jni/Android.mk +++ b/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 \ diff --git a/builtin/mainmenu/dlg_settings_advanced.lua b/builtin/mainmenu/dlg_settings_advanced.lua index 206ce1620..cac9f6983 100644 --- a/builtin/mainmenu/dlg_settings_advanced.lua +++ b/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 diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 0f2715ab5..53fb23859 100644 --- a/builtin/settingtypes.txt +++ b/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 diff --git a/minetest.conf.example b/minetest.conf.example index 2487dad34..d3831defa 100644 --- a/minetest.conf.example +++ b/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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6963d0306..08ea809c7 100644 --- a/src/CMakeLists.txt +++ b/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 diff --git a/src/guiFileSelectMenu.cpp b/src/guiFileSelectMenu.cpp deleted file mode 100644 index 65a07be39..000000000 --- a/src/guiFileSelectMenu.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - Minetest - Copyright (C) 2013 sapier - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "guiFileSelectMenu.h" - -GUIFileSelectMenu::GUIFileSelectMenu(gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, - const std::string &title, const std::string &formname) : - GUIModalMenu(env, parent, id, menumgr), - m_title(utf8_to_wide(title)), - m_accepted(false), - m_text_dst(NULL), - m_formname(formname) -{ -} - -GUIFileSelectMenu::~GUIFileSelectMenu() -{ - removeChildren(); - setlocale(LC_NUMERIC, "C"); -} - -void GUIFileSelectMenu::removeChildren() -{ - const core::list &children = getChildren(); - core::list children_copy; - for (core::list::ConstIterator i = children.begin(); i - != children.end(); i++) - { - children_copy.push_back(*i); - } - for (core::list::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); - - DesiredRect = rect; - recalculateAbsolutePosition(false); - - m_fileOpenDialog = - 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); - m_fileOpenDialog->setRelativePosition(pos); - m_fileOpenDialog->setMinSize(size); -} - -void GUIFileSelectMenu::drawMenu() -{ - gui::IGUISkin* skin = Environment->getSkin(); - if (!skin) - return; - - gui::IGUIElement::draw(); -} - -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 - fields[m_formname + "_canceled"] = m_formname; - - this->m_text_dst->gotText(fields); - } -} - -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; - } - } - return Parent ? Parent->OnEvent(event) : false; -} diff --git a/src/guiFileSelectMenu.h b/src/guiFileSelectMenu.h deleted file mode 100644 index 034823740..000000000 --- a/src/guiFileSelectMenu.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Minetest - Copyright (C) 2013 sapier - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef GUIFILESELECTMENU_H_ -#define GUIFILESELECTMENU_H_ - -#include - -#include "modalMenu.h" -#include "IGUIFileOpenDialog.h" -#include "guiFormSpecMenu.h" //required because of TextDest only !!! - -class GUIFileSelectMenu : public GUIModalMenu -{ -public: - GUIFileSelectMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, - IMenuManager *menumgr, const std::string &title, - const std::string &formid); - ~GUIFileSelectMenu(); - - void removeChildren(); - - /* - Remove and re-add (or reposition) stuff - */ - void regenerateGui(v2u32 screensize); - - void drawMenu(); - - bool OnEvent(const SEvent &event); - - void setTextDest(TextDest *dest) { m_text_dst = dest; } - -private: - void acceptInput(); - - std::wstring m_title; - bool m_accepted; - - gui::IGUIFileOpenDialog *m_fileOpenDialog; - - TextDest *m_text_dst; - - std::string m_formname; -}; - -#endif /* GUIFILESELECTMENU_H_ */ diff --git a/src/guiPathSelectMenu.cpp b/src/guiPathSelectMenu.cpp new file mode 100644 index 000000000..d992d8c0f --- /dev/null +++ b/src/guiPathSelectMenu.cpp @@ -0,0 +1,115 @@ +/* + Minetest + Copyright (C) 2013 sapier + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "guiPathSelectMenu.h" + +GUIFileSelectMenu::GUIFileSelectMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, + 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_file_select_dialog(is_file_select) +{ +} + +GUIFileSelectMenu::~GUIFileSelectMenu() +{ + removeChildren(); + setlocale(LC_NUMERIC, "C"); +} + +void GUIFileSelectMenu::regenerateGui(v2u32 screensize) +{ + removeChildren(); + m_fileOpenDialog = 0; + + core::dimension2du size(600, 400); + core::rect rect(0, 0, screensize.X, screensize.Y); + + DesiredRect = rect; + recalculateAbsolutePosition(false); + + m_fileOpenDialog = + 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); + m_fileOpenDialog->setRelativePosition(pos); + m_fileOpenDialog->setMinSize(size); +} + +void GUIFileSelectMenu::drawMenu() +{ + gui::IGUISkin *skin = Environment->getSkin(); + if (!skin) + return; + + gui::IGUIElement::draw(); +} + +void GUIFileSelectMenu::acceptInput() +{ + if ((m_text_dst != 0) && (this->m_formname != "")) { + StringMap fields; + if (m_accepted) { + std::string path; + if (!m_file_select_dialog) { + core::string 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) +{ + 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(); + 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; +} diff --git a/src/guiPathSelectMenu.h b/src/guiPathSelectMenu.h new file mode 100644 index 000000000..add4e36af --- /dev/null +++ b/src/guiPathSelectMenu.h @@ -0,0 +1,62 @@ +/* + Minetest + Copyright (C) 2013 sapier + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef GUIFILESELECTMENU_H_ +#define GUIFILESELECTMENU_H_ + +#include + +#include "modalMenu.h" +#include "IGUIFileOpenDialog.h" +#include "guiFormSpecMenu.h" //required because of TextDest only !!! + +class GUIFileSelectMenu : public GUIModalMenu +{ +public: + GUIFileSelectMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id, + IMenuManager *menumgr, const std::string &title, + const std::string &formid, bool is_file_select); + ~GUIFileSelectMenu(); + + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + bool OnEvent(const SEvent &event); + + void setTextDest(TextDest *dest) { m_text_dst = dest; } + +private: + void acceptInput(); + + std::wstring m_title; + bool m_accepted; + + gui::IGUIFileOpenDialog *m_fileOpenDialog; + + TextDest *m_text_dst; + + std::string m_formname; + bool m_file_select_dialog; +}; + +#endif /* GUIFILESELECTMENU_H_ */ diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 388971814..3ed2ba0e0 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/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); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index b5015add3..1d3e931e1 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/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); diff --git a/util/travis/clang-format-whitelist.txt b/util/travis/clang-format-whitelist.txt index 932f59978..66e312cdb 100644 --- a/util/travis/clang-format-whitelist.txt +++ b/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 -- cgit v1.2.3