Fix many formspec menu bugs
authorsapier <Sapier at GMX dot net>
Sun, 7 Jul 2013 19:53:40 +0000 (15:53 -0400)
committerkwolekr <kwolekr@minetest.net>
Sun, 7 Jul 2013 23:49:52 +0000 (19:49 -0400)
13 files changed:
builtin/mainmenu.lua
builtin/mainmenu_helper.lua
builtin/modmgr.lua
builtin/modstore.lua
doc/lua_api.txt
src/defaultsettings.cpp
src/environment.cpp
src/guiEngine.cpp
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h
src/itemdef.cpp
src/mapblock_mesh.cpp
src/shader.cpp

index c3808e7b96ad04626acdfd393e221c899ebd6e22..0f418d83a8ed7b0649c5106887c71795258e4cad 100644 (file)
@@ -50,7 +50,11 @@ function render_favourite(spec)
                details = details .. " "
        end
        
-       text = text .. ":" .. spec.port:trim()
+       if spec.port ~= nil then
+               text = text .. ":" .. spec.port:trim()
+       else
+               text = text .. ":??"
+       end
        
        return text
 end
@@ -113,6 +117,40 @@ function cleanup_path(temppath)
        return temppath
 end
 
+function menu.set_texture(identifier,gamedetails)
+       local texture_set = false
+       if menu.texturepack ~= nil then
+               local path = menu.basetexturedir .. 
+                                               gamedetails.id .. "_menu_" .. identifier .. ".png"
+               
+               if engine.set_background(identifier,path) then
+                       texture_set = true
+               end
+       end
+       
+       if not texture_set then
+               local path = gamedetails.path .. DIR_DELIM .."menu" .. 
+                                                                        DIR_DELIM .. identifier .. ".png"
+               if engine.set_background(identifier,path) then
+                       texture_set = true
+               end
+       end
+       
+       if not texture_set then
+               local path = menu.basetexturedir .. DIR_DELIM .."menu_" .. 
+                                                                               identifier .. ".png"
+               if engine.set_background(identifier,path) then
+                       texture_set = true
+               end
+       end
+       
+       if not texture_set then
+               local path = menu.defaulttexturedir .. DIR_DELIM .."menu_" .. 
+                                                                               identifier .. ".png"
+               engine.set_background(identifier,path)
+       end
+end
+
 --------------------------------------------------------------------------------
 function menu.update_gametype()
        if (menu.game_last_check == nil or
@@ -123,28 +161,33 @@ function menu.update_gametype()
                engine.set_topleft_text(gamedetails.name)
                
                --background
-               local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
-                                                                                                DIR_DELIM .. "background.png"
-               if engine.set_background("background",path_background_texture) then
-                       engine.set_clouds(false)
-               else
-                       engine.set_clouds(true)
+               local background_set = false
+               if menu.texturepack ~= nil then
+                       local path_background_texture = menu.basetexturedir .. 
+                                                                               gamedetails.id .. "_menu_background.png"
+                       
+                       if engine.set_background("background",path_background_texture) then
+                               background_set = true
+                               engine.set_clouds(false)
+                       end
                end
                
-               --overlay
-               local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
-                                                                                                DIR_DELIM .. "overlay.png"
-               engine.set_background("overlay",path_overlay_texture)
+               if not background_set then
+                       local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
+                                                                                DIR_DELIM .. "background.png"
+                       if engine.set_background("background",path_background_texture) then
+                               background_set = true
+                               engine.set_clouds(false)
+                       end
+               end
                
-               --header
-               local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
-                                                                                                DIR_DELIM .. "header.png"
-               engine.set_background("header",path_overlay_texture)
+               if not background_set then
+                       engine.set_clouds(true)
+               end
                
-               --footer
-               local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" .. 
-                                                                                                DIR_DELIM .. "footer.png"
-               engine.set_background("footer",path_overlay_texture)
+               menu.set_texture("overlay",gamedetails)
+               menu.set_texture("header",gamedetails)
+               menu.set_texture("footer",gamedetails)
                
                menu.game_last_check = menu.last_game
        else
@@ -258,7 +301,7 @@ function menu.filtered_game_list()
                        end
                        
                        retval = retval .. menu.worldlist[i].name .. 
-                                               " [[" .. menu.worldlist[i].gameid .. "]]"
+                                               " \\[" .. menu.worldlist[i].gameid .. "\\]"
                end
        end
        
@@ -324,9 +367,16 @@ function menu.init()
        end
        
        
-       menu.basetexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
+       menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
                                                DIR_DELIM .. "textures" .. DIR_DELIM .. "base" .. 
                                                DIR_DELIM .. "pack" .. DIR_DELIM
+       menu.basetexturedir = menu.defaulttexturedir
+       
+       menu.texturepack = engine.setting_get("texture_path")
+       
+       if menu.texturepack ~= nil then
+               menu.basetexturedir = menu.texturepack .. DIR_DELIM
+       end
 end
 
 --------------------------------------------------------------------------------
@@ -389,26 +439,27 @@ end
 
 --------------------------------------------------------------------------------
 function menubar.refresh()
-       menubar.formspec = "box[-2,7.625;15.75,1.75;000000]"
+       menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
+                                          "box[-0.3,5.6;12.4,0.05;FFFFFF]"
        menubar.buttons = {}
 
-       local button_base = -1.8
+       local button_base = -0.25
        
        local maxbuttons = #gamemgr.games
        
-       if maxbuttons > 12 then
-               maxbuttons = 12
+       if maxbuttons > 10 then
+               maxbuttons = 10
        end
        
        for i=1,maxbuttons,1 do
 
                local btn_name = "menubar_btn_" .. gamemgr.games[i].id
-               local buttonpos = button_base + (i-1) * 1.3
+               local buttonpos = button_base + (i-1) * 1.245
                if gamemgr.games[i].menuicon_path ~= nil and
                        gamemgr.games[i].menuicon_path ~= "" then
 
                        menubar.formspec = menubar.formspec ..
-                               "image_button[" .. buttonpos ..  ",7.9;1.3,1.3;"  ..
+                               "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;"  ..
                                gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
                else
                
@@ -422,7 +473,7 @@ function menubar.refresh()
                                text = text .. "\n" .. part3
                        end
                        menubar.formspec = menubar.formspec ..
-                               "image_button[" .. buttonpos ..  ",7.9;1.3,1.3;;" ..btn_name ..
+                               "image_button[" .. buttonpos ..  ",5.7;1.3,1.3;;" ..btn_name ..
                                ";" .. text .. ";true;true]"
                end
                
@@ -528,15 +579,30 @@ function tabbuilder.handle_create_world_buttons(fields)
                
                if gameindex > 0 and
                        worldname ~= "" then
-                       engine.setting_set("mg_name",fields["dd_mapgen"])
-                       local message = engine.create_world(worldname,gameindex)
+                       menu.worldlist = engine.get_worlds()
+                       
+                       local found = false
+                       for i=1,#menu.worldlist,1 do
+                               if worldlist[i].name == worldname then
+                                       found = true
+                                       break
+                               end
+                       end
+                       
+                       local message = nil
                        
-                       menu.last_game = gameindex
-                       engine.setting_set("main_menu_last_game_idx",gameindex)
+                       if not found then
+                               engine.setting_set("mg_name",fields["dd_mapgen"])
+                               message = engine.create_world(worldname,gameindex)
+                       else
+                               message = "A world named \"" .. worldname .. "\" already exists"
+                       end
                        
                        if message ~= nil then
                                gamedata.errormessage = message
                        else
+                               menu.last_game = gameindex
+                               engine.setting_set("main_menu_last_game_idx",gameindex)
                                menu.worldlist = engine.get_worlds()
                                
                                local worldlist = menu.worldlist
@@ -577,7 +643,7 @@ function tabbuilder.handle_delete_world_buttons(fields)
        
        if fields["world_delete_confirm"] then
                if menu.last_world > 0 and 
-                       menu.last_world < #menu.worldlist then
+                       menu.last_world <= #menu.worldlist then
                        engine.delete_world(menu.last_world)
                        menu.worldlist = engine.get_worlds()
                        menu.last_world = 1
@@ -591,16 +657,24 @@ end
 
 --------------------------------------------------------------------------------
 function tabbuilder.handle_multiplayer_buttons(fields)
+       
+       if fields["te_name"] ~= nil then
+               gamedata.playername = fields["te_name"]
+               engine.setting_set("name", fields["te_name"])
+       end
+       
        if fields["favourites"] ~= nil then
                local event = explode_textlist_event(fields["favourites"])
                if event.typ == "DCL" then
-                       gamedata.address = menu.favorites[event.index].name
+                       --gamedata.address = menu.favorites[event.index].name
                        if gamedata.address == nil then
                                gamedata.address = menu.favorites[event.index].address
                        end
                        gamedata.port = menu.favorites[event.index].port
                        gamedata.playername             = fields["te_name"]
-                       gamedata.password               = fields["te_pwd"]
+                       if fields["te_pwd"] ~= nil then
+                               gamedata.password               = fields["te_pwd"]
+                       end
                        gamedata.selected_world = 0
                        
                        if gamedata.address ~= nil and
@@ -622,10 +696,39 @@ function tabbuilder.handle_multiplayer_buttons(fields)
                                engine.setting_set("address",address)
                                engine.setting_set("port",port)
                        end
+                       
+                       menu.fav_selected = event.index
                end
                return
        end
        
+       if fields["key_up"] ~= nil or
+               fields["key_down"] ~= nil then
+               
+               local fav_idx = engine.get_textlist_index("favourites")
+               
+               if fields["key_up"] ~= nil and fav_idx > 1 then
+                       fav_idx = fav_idx -1
+               else if fields["key_down"] and fav_idx < #menu.favorites then
+                       fav_idx = fav_idx +1
+               end end
+               
+               local address = menu.favorites[fav_idx].name
+               if address == nil then
+                       address = menu.favorites[fav_idx].address
+               end
+               local port = menu.favorites[fav_idx].port
+               
+               if address ~= nil and
+                       port ~= nil then
+                       engine.setting_set("address",address)
+                       engine.setting_set("port",port)
+               end
+               
+               menu.fav_selected = fav_idx
+               return
+       end
+       
        if fields["cb_public_serverlist"] ~= nil then
                engine.setting_setbool("public_serverlist",
                        tabbuilder.tobool(fields["cb_public_serverlist"]))
@@ -635,6 +738,8 @@ function tabbuilder.handle_multiplayer_buttons(fields)
                else
                        menu.favorites = engine.get_favorites("local")
                end
+               
+               return
        end
 
        if fields["btn_delete_favorite"] ~= nil then
@@ -648,13 +753,15 @@ function tabbuilder.handle_multiplayer_buttons(fields)
                return
        end
 
-       if fields["btn_mp_connect"] ~= nil then
+       if fields["btn_mp_connect"] ~= nil or
+               fields["key_enter"] then
+               
                gamedata.playername             = fields["te_name"]
                gamedata.password               = fields["te_pwd"]
                gamedata.address                = fields["te_address"]
                gamedata.port                   = fields["te_port"]
                gamedata.selected_world = 0
-
+               
                engine.start()
                return
        end
@@ -665,12 +772,33 @@ function tabbuilder.handle_server_buttons(fields)
 
        local world_doubleclick = false
 
-       if fields["worlds"] ~= nil then
-               local event = explode_textlist_event(fields["worlds"])
+       if fields["srv_worlds"] ~= nil then
+               local event = explode_textlist_event(fields["srv_worlds"])
                
-               if event.typ == "DBL" then
+               if event.typ == "DCL" then
                        world_doubleclick = true
                end
+               if event.typ == "CHG" then
+                       engine.setting_set("main_menu_last_world_idx",engine.get_textlist_index("srv_worlds"))
+               end
+       end
+       
+               if fields["key_up"] then
+               local oldidx = engine.get_textlist_index("srv_worlds")
+               
+               if oldidx > 1 then
+                       local newidx = oldidx -1
+                       engine.setting_set("main_menu_last_world_idx",newidx)
+               end
+       end
+       
+       if fields["key_down"] then
+               local oldidx = engine.get_textlist_index("srv_worlds")
+               
+               if oldidx < #menu.worldlist then
+                       local newidx = oldidx + 1
+                       engine.setting_set("main_menu_last_world_idx",newidx)
+               end
        end
        
        if fields["cb_creative_mode"] then
@@ -680,15 +808,18 @@ function tabbuilder.handle_server_buttons(fields)
        if fields["cb_enable_damage"] then
                engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
        end
-
+       
+       
        if fields["start_server"] ~= nil or
-               world_doubleclick then
+               world_doubleclick or
+               fields["key_enter"] then
                local selected = engine.get_textlist_index("srv_worlds")
                if selected > 0 then
+                       
                        gamedata.playername             = fields["te_playername"]
-                       gamedata.password               = fields["te_pwd"]
-                       gamedata.address                = ""
+                       gamedata.password               = fields["te_passwd"]
                        gamedata.port                   = fields["te_serverport"]
+                       gamedata.address                = ""
                        gamedata.selected_world = selected
                        
                        engine.setting_set("main_menu_tab",tabbuilder.current_tab)
@@ -708,7 +839,7 @@ function tabbuilder.handle_server_buttons(fields)
        if fields["world_delete"] ~= nil then
                local selected = engine.get_textlist_index("srv_worlds")
                if selected > 0 then
-                       menu.last_world = engine.get_textlist_index("worlds")
+                       menu.last_world = engine.get_textlist_index("srv_worlds")
                        if menu.lastworld() ~= nil and
                                menu.lastworld().name ~= nil and
                                menu.lastworld().name ~= "" then
@@ -801,6 +932,28 @@ function tabbuilder.handle_singleplayer_buttons(fields)
                if event.typ == "DCL" then
                        world_doubleclick = true
                end
+               
+               if event.typ == "CHG" then
+                       engine.setting_set("main_menu_singleplayer_world_idx",engine.get_textlist_index("sp_worlds"))
+               end
+       end
+       
+       if fields["key_up"] then
+               local oldidx = engine.get_textlist_index("sp_worlds")
+               
+               if oldidx > 1 then
+                       local newidx = oldidx -1
+                       engine.setting_set("main_menu_singleplayer_world_idx",newidx)
+               end
+       end
+       
+       if fields["key_down"] then
+               local oldidx = engine.get_textlist_index("sp_worlds")
+               
+               if oldidx < #menu.filtered_game_list_raw() then
+                       local newidx = oldidx + 1
+                       engine.setting_set("main_menu_singleplayer_world_idx",newidx)
+               end
        end
        
        if fields["cb_creative_mode"] then
@@ -812,7 +965,8 @@ function tabbuilder.handle_singleplayer_buttons(fields)
        end
 
        if fields["play"] ~= nil or
-               world_doubleclick then
+               world_doubleclick or
+               fields["key_enter"] then
                local selected = engine.get_textlist_index("sp_worlds")
                if selected > 0 then
                        gamedata.selected_world = menu.filtered_index_to_plain(selected)
@@ -949,6 +1103,7 @@ end
 
 --------------------------------------------------------------------------------
 function tabbuilder.tab_multiplayer()
+
        local retval =
                "vertlabel[0,-0.25;CLIENT]" ..
                "label[1,-0.25;Favorites:]"..
@@ -971,14 +1126,25 @@ function tabbuilder.tab_multiplayer()
                        retval = retval .. "," .. render_favourite(menu.favorites[i])
                end
        end
-
-       retval = retval .. ";1]"
+       
+       print("cfav: " .. dump(menu.fav_selected))
+       if menu.fav_selected ~= nil then
+               retval = retval .. ";" .. menu.fav_selected .. "]"
+       else
+               retval = retval .. ";0]"
+       end
 
        return retval
 end
 
 --------------------------------------------------------------------------------
 function tabbuilder.tab_server()
+       local index = engine.setting_get("main_menu_last_world_idx")
+       
+       if index == nil then
+               index = 0
+       end
+       
        local retval = 
                "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
                "button[6.5,4.15;2.8,0.5;world_create;New]" ..
@@ -998,15 +1164,15 @@ function tabbuilder.tab_server()
        
        if #menu.worldlist > 0 then
                retval = retval .. menu.worldlist[1].name .. 
-                                               " [[" .. menu.worldlist[1].gameid .. "]]"
+                                               " \\[" .. menu.worldlist[1].gameid .. "\\]"
                                
                for i=2,#menu.worldlist,1 do
                        retval = retval .. "," .. menu.worldlist[i].name .. 
-                                               " [[" .. menu.worldlist[i].gameid .. "]]"
+                                               " \\[" .. menu.worldlist[i].gameid .. "\\]"
                end
        end
                                
-       retval = retval .. ";" .. menu.last_world .. "]"
+       retval = retval .. ";" .. index .. "]"
                
        return retval
 end
@@ -1061,7 +1227,7 @@ function tabbuilder.tab_credits()
        return  "vertlabel[0,-0.5;CREDITS]" ..
                        "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
                        "label[0.5,3.3;http://minetest.net]" .. 
-                       "image[0.5,1;" .. menu.basetexturedir .. "logo.png]" ..
+                       "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
                        "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
                        "#FFFF00Core Developers," ..
                        "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
index f5a470b725ba72752ea32e7834bd0deb22bfe13a..a204b4a37abf206d4a16ed8338ae14578a261590 100644 (file)
@@ -77,9 +77,9 @@ function fs_escape_string(text)
                        text = newtext
                end
                
-               text = text:gsub("%[","%[%[")
-               text = text:gsub("]","]]")
-               text = text:gsub(";"," ")
+               text = text:gsub("%[","\\%[")
+               text = text:gsub("]","\\]")
+               text = text:gsub(";","\\;")
        end
        return text
 end
index 045b529859a7a59ae78c0416cc4b59d5b0d62a35..a8ae4f1d8a30662368f91fcadfe5837c9990d2a8 100644 (file)
@@ -399,15 +399,20 @@ function modmgr.dialog_configure_world()
                local worldmodidx = modmgr.get_worldmod_idx()
                modname = modmgr.global_mods[worldmodidx]
 
-               if modname:find("<MODPACK>") ~= nil then
-                       modname = modname:sub(0,modname:find("<") -2)
-                       modpack_selected = true
-               end
+               if modname ~= nil then
+               
+                       if modname:find("<MODPACK>") ~= nil then
+                               modname = modname:sub(0,modname:find("<") -2)
+                               modpack_selected = true
+                       end
                
-               local parts = modmgr.global_mods[worldmodidx]:split(DIR_DELIM)
-               shortname = parts[#parts]
+                       local parts = modmgr.global_mods[worldmodidx]:split(DIR_DELIM)
+                       shortname = parts[#parts]
                
-               modfolder = engine.get_modpath() .. DIR_DELIM .. modname
+                       modfolder = engine.get_modpath() .. DIR_DELIM .. modname
+               else
+                       modname = ""
+               end
        end
 
        local worldspec = engine.get_worlds()[modmgr.world_config_selected_world]
index 1890da13800e25a31c3bec58e64de48bd480a86b..2c9e69069411e2373515ee1e1a910077ea470923 100644 (file)
@@ -273,3 +273,4 @@ function modstore.get_details(modid)
        modstore.details_cache[modid] = retval
        return retval
 end
+
index 5a2fdf10290b0b4dd387972761c439c42e392987..daef00d8b8af4b8cc0d15819f8b17061a42c2df6 100644 (file)
@@ -960,11 +960,21 @@ textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]
 ^Scrollabel itemlist showing arbitrary text elements
 ^ x and y position the itemlist relative to the top left of the menu
 ^ w and h are the size of the itemlist
-^ listelements can be prepended by #RRGGBB in hexadecimal format
+^ name fieldname sent to server on doubleclick value is current selected element
+^ listelements can be prepended by #colorkey (see colorkeys), 
 ^    if you want a listelement to start with # write ##
+
+textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]
+^Scrollabel itemlist showing arbitrary text elements
+^ x and y position the itemlist relative to the top left of the menu
+^ w and h are the size of the itemlist
 ^ name fieldname sent to server on doubleclick value is current selected element
+^ listelements can be prepended by #RRGGBB in hexadecimal format
+^    if you want a listelement to start with # write ##
+^ index to be selected within textlist
+^ true/false draw transparent background
 
-tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>;<current_tab>;<transparent>;<draw_border>]
+tabheader[<X>,<Y>;<name>;<caption 1>,<caption 2>,...,<caption n>;<current_tab>;<transparent>;<draw_border>]
 ^ show a tabHEADER at specific position (ignores formsize)
 ^ x and y position the itemlist relative to the top left of the menu
 ^ name fieldname data is transfered to lua
@@ -977,8 +987,19 @@ box[<X>,<Y>;<W>,<H>;<color>]
 ^ simple colored semitransparent box
 ^ x and y position the box relative to the top left of the menu
 ^ w and h are the size of box
+^ colorkey (see colorkeys)
+
+dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
+^ show a dropdown field
+^ x and y position of dropdown
+^ width of dropdown
+^ fieldname data is transfered to lua
+^ items to be shown in dropdown
+^ index of currently selected dropdown item
 ^ color in hexadecimal format RRGGBB
 
+Note: do NOT use a element name starting with "key_" those names are reserved to
+pass key press events to formspec! 
 
 Inventory location:
 
index 101eb35a4def3dfc28ec70ccc29eed21cd9a34ec..b6ee5e71cc1f0a3b6611a8ed80dcc0be96d08fbf 100644 (file)
@@ -126,8 +126,8 @@ void set_default_settings(Settings *settings)
        settings->setDefault("bilinear_filter", "false");
        settings->setDefault("trilinear_filter", "false");
        settings->setDefault("preload_item_visuals", "true");
-       settings->setDefault("enable_shaders", "2");
        settings->setDefault("enable_bumpmapping", "false");
+       settings->setDefault("enable_shaders", "true");
        settings->setDefault("repeat_rightclick_time", "0.25");
        settings->setDefault("enable_particles", "true");
 
index 21a6258b795631367c7e6b6c5051fc253a2328d9..cd87839847236f28b310f8c10007e7a3b7a87a52 100644 (file)
@@ -204,7 +204,7 @@ void Environment::printPlayers(std::ostream &o)
 
 u32 Environment::getDayNightRatio()
 {
-       bool smooth = (g_settings->getS32("enable_shaders") != 0);
+       bool smooth = g_settings->getBool("enable_shaders");
        return time_to_daynight_ratio(m_time_of_day_f*24000, smooth);
 }
 
index 2c5000d8bbae40eca90004fc09368ba19b674da3..f3b3a68456f69ccc339d67a2ee90da619b326e8a 100644 (file)
@@ -182,7 +182,7 @@ GUIEngine::GUIEngine(       irr::IrrlichtDevice* dev,
                        errorstream
                                << "GUIEngine::GUIEngine unable to load builtin menu"
                                << std::endl;
-                       return;
+                       assert("no future without mainmenu" == 0);
                }
        }
 
index 9947306193509a2fc030ee844e89a03e907001a2..abe519798ed404b34e997ae5d21e70cba8f80a8a 100644 (file)
@@ -171,6 +171,10 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
        m_use_gettext(false),
        m_lock(false)
 {
+       current_keys_pending.key_down = false;
+       current_keys_pending.key_up = false;
+       current_keys_pending.key_enter = false;
+
 }
 
 GUIFormSpecMenu::~GUIFormSpecMenu()
@@ -243,28 +247,25 @@ std::vector<std::string> split(const std::string &s, char delim, bool escape=fal
        else {
                std::string current = "";
                current += s.c_str()[0];
-               bool last_was_delim = false;
+               bool last_was_escape = false;
                for(unsigned int i=1; i < s.size(); i++) {
-                       if (last_was_delim) {
+                       if (last_was_escape) {
+                               current += '\\';
+                               current += s.c_str()[i];
+                               last_was_escape = false;
+                       }
+                       else {
                                if (s.c_str()[i] == delim) {
-                                       current += s.c_str()[i];
-                                       last_was_delim = false;
-                               }
-                               else {
                                        tokens.push_back(current);
-
                                        current = "";
-                                       current += s.c_str()[i];
-                                       last_was_delim = false;
+                                       last_was_escape = false;
                                }
-                       }
-                       else {
-                               if (s.c_str()[i] == delim) {
-                                       last_was_delim = true;
+                               else if (s.c_str()[i] == '\\'){
+                                       last_was_escape = true;
                                }
                                else {
-                                       last_was_delim = false;
                                        current += s.c_str()[i];
+                                       last_was_escape = false;
                                }
                        }
                }
@@ -659,32 +660,34 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) {
                for (unsigned int i=0; i < items.size(); i++) {
                        if (items[i].c_str()[0] == '#') {
                                if (items[i].c_str()[1] == '#') {
-                                       e->addItem(narrow_to_wide(items[i]).c_str() +1);
+                                       e->addItem(narrow_to_wide(unescape_string(items[i])).c_str() +1);
                                }
                                else {
-                                       std::wstring toadd = narrow_to_wide(items[i].c_str() + 7);
                                        std::string color = items[i].substr(1,6);
+                                       std::wstring toadd =
+                                               narrow_to_wide(unescape_string(items[i]).c_str() + 7);
+
 
                                        e->addItem(toadd.c_str());
 
                                        irr::video::SColor toset;
 
-                                       if (parseColor(color,toset))
+                                       if (parseColor(color, toset))
                                                e->setItemOverrideColor(i,toset);
                                }
                        }
                        else {
-                       e->addItem(narrow_to_wide(items[i]).c_str());
+                               e->addItem(narrow_to_wide(unescape_string(items[i])).c_str());
                        }
                }
 
-               if (str_initial_selection != "")
-                       e->setSelected(stoi(str_initial_selection.c_str())-1);
-
                if (data->listbox_selections.find(fname_w) != data->listbox_selections.end()) {
                        e->setSelected(data->listbox_selections[fname_w]);
                }
 
+               if (str_initial_selection != "")
+                       e->setSelected(stoi(str_initial_selection.c_str())-1);
+
                m_listboxes.push_back(std::pair<FieldSpec,gui::IGUIListBox*>(spec,e));
                m_fields.push_back(spec);
                return;
@@ -1335,7 +1338,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) {
 
                irr::video::SColor color;
 
-               if (parseColor(color_str,color)) {
+               if (parseColor(color_str, color)) {
                        BoxDrawSpec spec(pos,geom,color);
 
                        m_boxes.push_back(spec);
@@ -1355,8 +1358,19 @@ void GUIFormSpecMenu::parseElement(parserData* data,std::string element) {
 
        std::vector<std::string> parts = split(element,'[', true);
 
-       if (parts.size() != 2)
+       // ugly workaround to keep compatibility
+       if (parts.size() > 2) {
+               if (trim(parts[0]) == "image") {
+                       for (unsigned int i=2;i< parts.size(); i++) {
+                               parts[1] += "[" + parts[i];
+                       }
+               }
+               else { return; }
+       }
+
+       if (parts.size() < 2) {
                return;
+       }
 
        std::string type = trim(parts[0]);
        std::string description = trim(parts[1]);
@@ -2010,6 +2024,26 @@ void GUIFormSpecMenu::acceptInput(int eventtype)
        {
                std::map<std::string, std::string> fields;
 
+               if (current_keys_pending.key_down) {
+                       fields["key_down"] = "true";
+                       current_keys_pending.key_down = false;
+               }
+
+               if (current_keys_pending.key_up) {
+                       fields["key_up"] = "true";
+                       current_keys_pending.key_up = false;
+               }
+
+               if (current_keys_pending.key_enter) {
+                       fields["key_enter"] = "true";
+                       current_keys_pending.key_enter = false;
+               }
+
+               if (current_keys_pending.key_escape) {
+                       fields["key_escape"] = "true";
+                       current_keys_pending.key_escape = false;
+               }
+
                for(u32 i=0; i<m_fields.size(); i++)
                {
                        const FieldSpec &s = m_fields[i];
@@ -2101,16 +2135,38 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                                m_text_dst->gotText(narrow_to_wide("MenuQuit"));
                        return true;
                }
-               if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
-               {
+               if (event.KeyInput.PressedDown &&
+                       (event.KeyInput.Key==KEY_RETURN ||
+                        event.KeyInput.Key==KEY_UP ||
+                        event.KeyInput.Key==KEY_DOWN)
+                       ) {
+
+
+                       switch (event.KeyInput.Key) {
+                               case KEY_RETURN:
+                                       if (m_allowclose) {
+                                               acceptInput();
+                                               quitMenu();
+                                       }
+                                       else
+                                               current_keys_pending.key_enter = true;
+                                       break;
+                               case KEY_UP:
+                                       current_keys_pending.key_up = true;
+                                       break;
+                               case KEY_DOWN:
+                                       current_keys_pending.key_down = true;
+                                       break;
+                               break;
+                               default:
+                                       //can't happen at all!
+                                       assert("reached a source line that can't ever been reached" == 0);
+                                       break;
+                       }
                        acceptInput();
-
-                       if (m_allowclose)
-                               quitMenu();
-                       else
-                               m_text_dst->gotText(narrow_to_wide("KeyEnter"));
                        return true;
                }
+
        }
        if(event.EventType==EET_MOUSE_INPUT_EVENT
                        && event.MouseInput.Event != EMIE_MOUSE_MOVED)
@@ -2477,11 +2533,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                {
                        if(event.GUIEvent.Caller->getID() > 257)
                        {
-                               acceptInput();
-                               if (m_allowclose)
+
+                               if (m_allowclose) {
+                                       acceptInput();
                                        quitMenu();
-                               else
-                                       m_text_dst->gotText(narrow_to_wide("EditBoxEnter"));
+                               }
+                               else {
+                                       current_keys_pending.key_enter = true;
+                                       acceptInput();
+                               }
                                // quitMenu deallocates menu
                                return true;
                        }
@@ -2519,15 +2579,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 bool GUIFormSpecMenu::parseColor(std::string color, irr::video::SColor& outcolor) {
        outcolor = irr::video::SColor(0,0,0,0);
 
-       if(!string_allowed(color, "0123456789abcdefABCDEF"))
+       if (!string_allowed(color, "0123456789abcdefABCDEF"))
                return false;
 
        u32 color_value;
        std::istringstream iss(color);
        iss >> std::hex >> color_value;
+       
        outcolor = irr::video::SColor(color_value);
 
        outcolor.setAlpha(255);
        return true;
 }
-
index 60d170fda10fd2ed821799ce977d1b9854ddcd98..116f7b95d54ac4cd3bf3d63523bae65d468bf4c8 100644 (file)
@@ -297,8 +297,17 @@ private:
                std::map<std::wstring,int> listbox_selections;
        } parserData;
 
+       typedef struct {
+               bool key_up;
+               bool key_down;
+               bool key_enter;
+               bool key_escape;
+       } fs_key_pendig;
+
        std::vector<video::ITexture *> m_Textures;
 
+       fs_key_pendig current_keys_pending;
+
        void parseElement(parserData* data,std::string element);
 
        void parseSize(parserData* data,std::string element);
@@ -321,7 +330,7 @@ private:
        void parseTabHeader(parserData* data,std::string element);
        void parseBox(parserData* data,std::string element);
 
-       bool parseColor(std::string color, irr::video::SColor& outcolor);
+       bool parseColor(std::string color, irr::video::SColor& outcolor); 
 };
 
 class FormspecFormSource: public IFormSource
index 238ff58c0ae610642fef42aaee380c882f5f838b..f692ccf5536fbdeda71f9c9817a5fbe153ce3dbb 100644 (file)
@@ -389,7 +389,7 @@ public:
                        scene::IMesh *node_mesh = mapblock_mesh.getMesh();
                        assert(node_mesh);
                        video::SColor c(255, 255, 255, 255);
-                       if(g_settings->getS32("enable_shaders") != 0)
+                       if(g_settings->getBool("enable_shaders"))
                                c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source));
                        setMeshColor(node_mesh, c);
 
index 5e4d713b0107e4f676198e2607e43680717c9d75..4386a1f1356466795b711e44664af65f24d37aca 100644 (file)
@@ -1069,10 +1069,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
 
        /*
                Convert MeshCollector to SMesh
-               Also store animation info
        */
-       bool enable_shaders = (g_settings->getS32("enable_shaders") > 0);
        bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
+       bool enable_shaders = g_settings->getBool("enable_shaders");
        video::E_MATERIAL_TYPE shadermat1 = m_gamedef->getShaderSource()->
                        getShader("test_shader_1").material;
        video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()->
index 58042e6515a43c95e0743a3d4baf4dfcf89ff2bd..19b8d7c9d9b2306d6305c56c96156167705a7752 100644 (file)
@@ -362,7 +362,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
        Load shader programs
 */
 void load_shaders(std::string name, SourceShaderCache *sourcecache,
-               video::E_DRIVER_TYPE drivertype, s32 enable_shaders,
+               video::E_DRIVER_TYPE drivertype, bool enable_shaders,
                std::string &vertex_program, std::string &pixel_program,
                std::string &geometry_program, bool &is_highlevel);
 
@@ -625,8 +625,8 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
        }
 
        // 0 = off, 1 = assembly shaders only, 2 = highlevel or assembly
-       s32 enable_shaders = g_settings->getS32("enable_shaders");
-       if(enable_shaders <= 0)
+       bool enable_shaders = g_settings->getBool("enable_shaders");
+       if(!enable_shaders)
                return shaderinfo;
 
        video::IVideoDriver* driver = device->getVideoDriver();
@@ -748,7 +748,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
 }
 
 void load_shaders(std::string name, SourceShaderCache *sourcecache,
-               video::E_DRIVER_TYPE drivertype, s32 enable_shaders,
+               video::E_DRIVER_TYPE drivertype, bool enable_shaders,
                std::string &vertex_program, std::string &pixel_program,
                std::string &geometry_program, bool &is_highlevel)
 {
@@ -757,7 +757,7 @@ void load_shaders(std::string name, SourceShaderCache *sourcecache,
        geometry_program = "";
        is_highlevel = false;
 
-       if(enable_shaders >= 2){
+       if(enable_shaders){
                // Look for high level shaders
                if(drivertype == video::EDT_DIRECT3D9){
                        // Direct3D 9: HLSL
@@ -778,7 +778,7 @@ void load_shaders(std::string name, SourceShaderCache *sourcecache,
                }
        }
 
-       if(enable_shaders >= 1){
+       if(enable_shaders){
                // Look for assembly shaders
                if(drivertype == video::EDT_DIRECT3D8){
                        // Direct3D 8 assembly shaders