Fix many formspec menu bugs

This commit is contained in:
sapier 2013-07-07 15:53:40 -04:00 committed by kwolekr
parent 7e73b7cae9
commit 88d43af276
13 changed files with 377 additions and 116 deletions

@ -50,7 +50,11 @@ function render_favourite(spec)
details = details .. " " details = details .. " "
end end
if spec.port ~= nil then
text = text .. ":" .. spec.port:trim() text = text .. ":" .. spec.port:trim()
else
text = text .. ":??"
end
return text return text
end end
@ -113,6 +117,40 @@ function cleanup_path(temppath)
return temppath return temppath
end 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() function menu.update_gametype()
if (menu.game_last_check == nil or if (menu.game_last_check == nil or
@ -123,28 +161,33 @@ function menu.update_gametype()
engine.set_topleft_text(gamedetails.name) engine.set_topleft_text(gamedetails.name)
--background --background
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
if not background_set then
local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" .. local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" ..
DIR_DELIM .. "background.png" DIR_DELIM .. "background.png"
if engine.set_background("background",path_background_texture) then if engine.set_background("background",path_background_texture) then
background_set = true
engine.set_clouds(false) engine.set_clouds(false)
else end
end
if not background_set then
engine.set_clouds(true) engine.set_clouds(true)
end end
--overlay menu.set_texture("overlay",gamedetails)
local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" .. menu.set_texture("header",gamedetails)
DIR_DELIM .. "overlay.png" menu.set_texture("footer",gamedetails)
engine.set_background("overlay",path_overlay_texture)
--header
local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" ..
DIR_DELIM .. "header.png"
engine.set_background("header",path_overlay_texture)
--footer
local path_overlay_texture = gamedetails.path .. DIR_DELIM .."menu" ..
DIR_DELIM .. "footer.png"
engine.set_background("footer",path_overlay_texture)
menu.game_last_check = menu.last_game menu.game_last_check = menu.last_game
else else
@ -258,7 +301,7 @@ function menu.filtered_game_list()
end end
retval = retval .. menu.worldlist[i].name .. retval = retval .. menu.worldlist[i].name ..
" [[" .. menu.worldlist[i].gameid .. "]]" " \\[" .. menu.worldlist[i].gameid .. "\\]"
end end
end end
@ -324,9 +367,16 @@ function menu.init()
end end
menu.basetexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." .. menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
DIR_DELIM .. "textures" .. DIR_DELIM .. "base" .. DIR_DELIM .. "textures" .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM 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 end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -389,26 +439,27 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function menubar.refresh() 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 = {} menubar.buttons = {}
local button_base = -1.8 local button_base = -0.25
local maxbuttons = #gamemgr.games local maxbuttons = #gamemgr.games
if maxbuttons > 12 then if maxbuttons > 10 then
maxbuttons = 12 maxbuttons = 10
end end
for i=1,maxbuttons,1 do for i=1,maxbuttons,1 do
local btn_name = "menubar_btn_" .. gamemgr.games[i].id 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 if gamemgr.games[i].menuicon_path ~= nil and
gamemgr.games[i].menuicon_path ~= "" then gamemgr.games[i].menuicon_path ~= "" then
menubar.formspec = menubar.formspec .. 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]" gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
else else
@ -422,7 +473,7 @@ function menubar.refresh()
text = text .. "\n" .. part3 text = text .. "\n" .. part3
end end
menubar.formspec = menubar.formspec .. 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]" ";" .. text .. ";true;true]"
end end
@ -528,15 +579,30 @@ function tabbuilder.handle_create_world_buttons(fields)
if gameindex > 0 and if gameindex > 0 and
worldname ~= "" then worldname ~= "" then
engine.setting_set("mg_name",fields["dd_mapgen"]) menu.worldlist = engine.get_worlds()
local message = engine.create_world(worldname,gameindex)
menu.last_game = gameindex local found = false
engine.setting_set("main_menu_last_game_idx",gameindex) for i=1,#menu.worldlist,1 do
if worldlist[i].name == worldname then
found = true
break
end
end
local message = nil
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 if message ~= nil then
gamedata.errormessage = message gamedata.errormessage = message
else else
menu.last_game = gameindex
engine.setting_set("main_menu_last_game_idx",gameindex)
menu.worldlist = engine.get_worlds() menu.worldlist = engine.get_worlds()
local worldlist = menu.worldlist local worldlist = menu.worldlist
@ -577,7 +643,7 @@ function tabbuilder.handle_delete_world_buttons(fields)
if fields["world_delete_confirm"] then if fields["world_delete_confirm"] then
if menu.last_world > 0 and if menu.last_world > 0 and
menu.last_world < #menu.worldlist then menu.last_world <= #menu.worldlist then
engine.delete_world(menu.last_world) engine.delete_world(menu.last_world)
menu.worldlist = engine.get_worlds() menu.worldlist = engine.get_worlds()
menu.last_world = 1 menu.last_world = 1
@ -591,16 +657,24 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.handle_multiplayer_buttons(fields) 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 if fields["favourites"] ~= nil then
local event = explode_textlist_event(fields["favourites"]) local event = explode_textlist_event(fields["favourites"])
if event.typ == "DCL" then if event.typ == "DCL" then
gamedata.address = menu.favorites[event.index].name --gamedata.address = menu.favorites[event.index].name
if gamedata.address == nil then if gamedata.address == nil then
gamedata.address = menu.favorites[event.index].address gamedata.address = menu.favorites[event.index].address
end end
gamedata.port = menu.favorites[event.index].port gamedata.port = menu.favorites[event.index].port
gamedata.playername = fields["te_name"] gamedata.playername = fields["te_name"]
if fields["te_pwd"] ~= nil then
gamedata.password = fields["te_pwd"] gamedata.password = fields["te_pwd"]
end
gamedata.selected_world = 0 gamedata.selected_world = 0
if gamedata.address ~= nil and if gamedata.address ~= nil and
@ -622,10 +696,39 @@ function tabbuilder.handle_multiplayer_buttons(fields)
engine.setting_set("address",address) engine.setting_set("address",address)
engine.setting_set("port",port) engine.setting_set("port",port)
end end
menu.fav_selected = event.index
end end
return return
end 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 if fields["cb_public_serverlist"] ~= nil then
engine.setting_setbool("public_serverlist", engine.setting_setbool("public_serverlist",
tabbuilder.tobool(fields["cb_public_serverlist"])) tabbuilder.tobool(fields["cb_public_serverlist"]))
@ -635,6 +738,8 @@ function tabbuilder.handle_multiplayer_buttons(fields)
else else
menu.favorites = engine.get_favorites("local") menu.favorites = engine.get_favorites("local")
end end
return
end end
if fields["btn_delete_favorite"] ~= nil then if fields["btn_delete_favorite"] ~= nil then
@ -648,7 +753,9 @@ function tabbuilder.handle_multiplayer_buttons(fields)
return return
end 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.playername = fields["te_name"]
gamedata.password = fields["te_pwd"] gamedata.password = fields["te_pwd"]
gamedata.address = fields["te_address"] gamedata.address = fields["te_address"]
@ -665,12 +772,33 @@ function tabbuilder.handle_server_buttons(fields)
local world_doubleclick = false local world_doubleclick = false
if fields["worlds"] ~= nil then if fields["srv_worlds"] ~= nil then
local event = explode_textlist_event(fields["worlds"]) local event = explode_textlist_event(fields["srv_worlds"])
if event.typ == "DBL" then if event.typ == "DCL" then
world_doubleclick = true world_doubleclick = true
end 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 end
if fields["cb_creative_mode"] then if fields["cb_creative_mode"] then
@ -681,14 +809,17 @@ function tabbuilder.handle_server_buttons(fields)
engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"])) engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
end end
if fields["start_server"] ~= nil or if fields["start_server"] ~= nil or
world_doubleclick then world_doubleclick or
fields["key_enter"] then
local selected = engine.get_textlist_index("srv_worlds") local selected = engine.get_textlist_index("srv_worlds")
if selected > 0 then if selected > 0 then
gamedata.playername = fields["te_playername"] gamedata.playername = fields["te_playername"]
gamedata.password = fields["te_pwd"] gamedata.password = fields["te_passwd"]
gamedata.address = ""
gamedata.port = fields["te_serverport"] gamedata.port = fields["te_serverport"]
gamedata.address = ""
gamedata.selected_world = selected gamedata.selected_world = selected
engine.setting_set("main_menu_tab",tabbuilder.current_tab) 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 if fields["world_delete"] ~= nil then
local selected = engine.get_textlist_index("srv_worlds") local selected = engine.get_textlist_index("srv_worlds")
if selected > 0 then 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 if menu.lastworld() ~= nil and
menu.lastworld().name ~= nil and menu.lastworld().name ~= nil and
menu.lastworld().name ~= "" then menu.lastworld().name ~= "" then
@ -801,6 +932,28 @@ function tabbuilder.handle_singleplayer_buttons(fields)
if event.typ == "DCL" then if event.typ == "DCL" then
world_doubleclick = true world_doubleclick = true
end 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 end
if fields["cb_creative_mode"] then if fields["cb_creative_mode"] then
@ -812,7 +965,8 @@ function tabbuilder.handle_singleplayer_buttons(fields)
end end
if fields["play"] ~= nil or if fields["play"] ~= nil or
world_doubleclick then world_doubleclick or
fields["key_enter"] then
local selected = engine.get_textlist_index("sp_worlds") local selected = engine.get_textlist_index("sp_worlds")
if selected > 0 then if selected > 0 then
gamedata.selected_world = menu.filtered_index_to_plain(selected) gamedata.selected_world = menu.filtered_index_to_plain(selected)
@ -949,6 +1103,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.tab_multiplayer() function tabbuilder.tab_multiplayer()
local retval = local retval =
"vertlabel[0,-0.25;CLIENT]" .. "vertlabel[0,-0.25;CLIENT]" ..
"label[1,-0.25;Favorites:]".. "label[1,-0.25;Favorites:]"..
@ -972,13 +1127,24 @@ function tabbuilder.tab_multiplayer()
end end
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 return retval
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.tab_server() function tabbuilder.tab_server()
local index = engine.setting_get("main_menu_last_world_idx")
if index == nil then
index = 0
end
local retval = local retval =
"button[4,4.15;2.6,0.5;world_delete;Delete]" .. "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
"button[6.5,4.15;2.8,0.5;world_create;New]" .. "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 if #menu.worldlist > 0 then
retval = retval .. menu.worldlist[1].name .. retval = retval .. menu.worldlist[1].name ..
" [[" .. menu.worldlist[1].gameid .. "]]" " \\[" .. menu.worldlist[1].gameid .. "\\]"
for i=2,#menu.worldlist,1 do for i=2,#menu.worldlist,1 do
retval = retval .. "," .. menu.worldlist[i].name .. retval = retval .. "," .. menu.worldlist[i].name ..
" [[" .. menu.worldlist[i].gameid .. "]]" " \\[" .. menu.worldlist[i].gameid .. "\\]"
end end
end end
retval = retval .. ";" .. menu.last_world .. "]" retval = retval .. ";" .. index .. "]"
return retval return retval
end end
@ -1061,7 +1227,7 @@ function tabbuilder.tab_credits()
return "vertlabel[0,-0.5;CREDITS]" .. return "vertlabel[0,-0.5;CREDITS]" ..
"label[0.5,3;Minetest " .. engine.get_version() .. "]" .. "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
"label[0.5,3.3;http://minetest.net]" .. "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;" .. "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
"#FFFF00Core Developers," .. "#FFFF00Core Developers," ..
"Perttu Ahola (celeron55) <celeron55@gmail.com>,".. "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..

@ -77,9 +77,9 @@ function fs_escape_string(text)
text = newtext text = newtext
end end
text = text:gsub("%[","%[%[") text = text:gsub("%[","\\%[")
text = text:gsub("]","]]") text = text:gsub("]","\\]")
text = text:gsub(";"," ") text = text:gsub(";","\\;")
end end
return text return text
end end

@ -399,6 +399,8 @@ function modmgr.dialog_configure_world()
local worldmodidx = modmgr.get_worldmod_idx() local worldmodidx = modmgr.get_worldmod_idx()
modname = modmgr.global_mods[worldmodidx] modname = modmgr.global_mods[worldmodidx]
if modname ~= nil then
if modname:find("<MODPACK>") ~= nil then if modname:find("<MODPACK>") ~= nil then
modname = modname:sub(0,modname:find("<") -2) modname = modname:sub(0,modname:find("<") -2)
modpack_selected = true modpack_selected = true
@ -408,6 +410,9 @@ function modmgr.dialog_configure_world()
shortname = parts[#parts] shortname = parts[#parts]
modfolder = engine.get_modpath() .. DIR_DELIM .. modname modfolder = engine.get_modpath() .. DIR_DELIM .. modname
else
modname = ""
end
end end
local worldspec = engine.get_worlds()[modmgr.world_config_selected_world] local worldspec = engine.get_worlds()[modmgr.world_config_selected_world]

@ -273,3 +273,4 @@ function modstore.get_details(modid)
modstore.details_cache[modid] = retval modstore.details_cache[modid] = retval
return retval return retval
end end

@ -960,11 +960,21 @@ textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]
^Scrollabel itemlist showing arbitrary text elements ^Scrollabel itemlist showing arbitrary text elements
^ x and y position the itemlist relative to the top left of the menu ^ x and y position the itemlist relative to the top left of the menu
^ w and h are the size of the itemlist ^ 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 #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 ^ listelements can be prepended by #RRGGBB in hexadecimal format
^ if you want a listelement to start with # write ## ^ if you want a listelement to start with # write ##
^ name fieldname sent to server on doubleclick value is current selected element ^ 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) ^ show a tabHEADER at specific position (ignores formsize)
^ x and y position the itemlist relative to the top left of the menu ^ x and y position the itemlist relative to the top left of the menu
^ name fieldname data is transfered to lua ^ name fieldname data is transfered to lua
@ -977,8 +987,19 @@ box[<X>,<Y>;<W>,<H>;<color>]
^ simple colored semitransparent box ^ simple colored semitransparent box
^ x and y position the box relative to the top left of the menu ^ x and y position the box relative to the top left of the menu
^ w and h are the size of box ^ 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 ^ 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: Inventory location:

@ -126,8 +126,8 @@ void set_default_settings(Settings *settings)
settings->setDefault("bilinear_filter", "false"); settings->setDefault("bilinear_filter", "false");
settings->setDefault("trilinear_filter", "false"); settings->setDefault("trilinear_filter", "false");
settings->setDefault("preload_item_visuals", "true"); settings->setDefault("preload_item_visuals", "true");
settings->setDefault("enable_shaders", "2");
settings->setDefault("enable_bumpmapping", "false"); settings->setDefault("enable_bumpmapping", "false");
settings->setDefault("enable_shaders", "true");
settings->setDefault("repeat_rightclick_time", "0.25"); settings->setDefault("repeat_rightclick_time", "0.25");
settings->setDefault("enable_particles", "true"); settings->setDefault("enable_particles", "true");

@ -204,7 +204,7 @@ void Environment::printPlayers(std::ostream &o)
u32 Environment::getDayNightRatio() 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); return time_to_daynight_ratio(m_time_of_day_f*24000, smooth);
} }

@ -182,7 +182,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
errorstream errorstream
<< "GUIEngine::GUIEngine unable to load builtin menu" << "GUIEngine::GUIEngine unable to load builtin menu"
<< std::endl; << std::endl;
return; assert("no future without mainmenu" == 0);
} }
} }

@ -171,6 +171,10 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
m_use_gettext(false), m_use_gettext(false),
m_lock(false) m_lock(false)
{ {
current_keys_pending.key_down = false;
current_keys_pending.key_up = false;
current_keys_pending.key_enter = false;
} }
GUIFormSpecMenu::~GUIFormSpecMenu() GUIFormSpecMenu::~GUIFormSpecMenu()
@ -243,28 +247,25 @@ std::vector<std::string> split(const std::string &s, char delim, bool escape=fal
else { else {
std::string current = ""; std::string current = "";
current += s.c_str()[0]; current += s.c_str()[0];
bool last_was_delim = false; bool last_was_escape = false;
for(unsigned int i=1; i < s.size(); i++) { for(unsigned int i=1; i < s.size(); i++) {
if (last_was_delim) { if (last_was_escape) {
if (s.c_str()[i] == delim) { current += '\\';
current += s.c_str()[i]; current += s.c_str()[i];
last_was_delim = false; last_was_escape = false;
} }
else { else {
if (s.c_str()[i] == delim) {
tokens.push_back(current); tokens.push_back(current);
current = ""; current = "";
current += s.c_str()[i]; last_was_escape = false;
last_was_delim = false;
} }
else if (s.c_str()[i] == '\\'){
last_was_escape = true;
} }
else { else {
if (s.c_str()[i] == delim) {
last_was_delim = true;
}
else {
last_was_delim = false;
current += s.c_str()[i]; 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++) { for (unsigned int i=0; i < items.size(); i++) {
if (items[i].c_str()[0] == '#') { if (items[i].c_str()[0] == '#') {
if (items[i].c_str()[1] == '#') { 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 { else {
std::wstring toadd = narrow_to_wide(items[i].c_str() + 7);
std::string color = items[i].substr(1,6); 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()); e->addItem(toadd.c_str());
irr::video::SColor toset; irr::video::SColor toset;
if (parseColor(color,toset)) if (parseColor(color, toset))
e->setItemOverrideColor(i,toset); e->setItemOverrideColor(i,toset);
} }
} }
else { 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()) { if (data->listbox_selections.find(fname_w) != data->listbox_selections.end()) {
e->setSelected(data->listbox_selections[fname_w]); 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_listboxes.push_back(std::pair<FieldSpec,gui::IGUIListBox*>(spec,e));
m_fields.push_back(spec); m_fields.push_back(spec);
return; return;
@ -1335,7 +1338,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) {
irr::video::SColor color; irr::video::SColor color;
if (parseColor(color_str,color)) { if (parseColor(color_str, color)) {
BoxDrawSpec spec(pos,geom,color); BoxDrawSpec spec(pos,geom,color);
m_boxes.push_back(spec); 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); 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; return;
}
std::string type = trim(parts[0]); std::string type = trim(parts[0]);
std::string description = trim(parts[1]); std::string description = trim(parts[1]);
@ -2010,6 +2024,26 @@ void GUIFormSpecMenu::acceptInput(int eventtype)
{ {
std::map<std::string, std::string> fields; 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++) for(u32 i=0; i<m_fields.size(); i++)
{ {
const FieldSpec &s = m_fields[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")); m_text_dst->gotText(narrow_to_wide("MenuQuit"));
return true; return true;
} }
if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown) if (event.KeyInput.PressedDown &&
{ (event.KeyInput.Key==KEY_RETURN ||
acceptInput(); event.KeyInput.Key==KEY_UP ||
event.KeyInput.Key==KEY_DOWN)
) {
if (m_allowclose)
switch (event.KeyInput.Key) {
case KEY_RETURN:
if (m_allowclose) {
acceptInput();
quitMenu(); quitMenu();
}
else else
m_text_dst->gotText(narrow_to_wide("KeyEnter")); 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();
return true; return true;
} }
} }
if(event.EventType==EET_MOUSE_INPUT_EVENT if(event.EventType==EET_MOUSE_INPUT_EVENT
&& event.MouseInput.Event != EMIE_MOUSE_MOVED) && event.MouseInput.Event != EMIE_MOUSE_MOVED)
@ -2477,11 +2533,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
{ {
if(event.GUIEvent.Caller->getID() > 257) if(event.GUIEvent.Caller->getID() > 257)
{ {
if (m_allowclose) {
acceptInput(); acceptInput();
if (m_allowclose)
quitMenu(); quitMenu();
else }
m_text_dst->gotText(narrow_to_wide("EditBoxEnter")); else {
current_keys_pending.key_enter = true;
acceptInput();
}
// quitMenu deallocates menu // quitMenu deallocates menu
return true; return true;
} }
@ -2519,15 +2579,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
bool GUIFormSpecMenu::parseColor(std::string color, irr::video::SColor& outcolor) { bool GUIFormSpecMenu::parseColor(std::string color, irr::video::SColor& outcolor) {
outcolor = irr::video::SColor(0,0,0,0); outcolor = irr::video::SColor(0,0,0,0);
if(!string_allowed(color, "0123456789abcdefABCDEF")) if (!string_allowed(color, "0123456789abcdefABCDEF"))
return false; return false;
u32 color_value; u32 color_value;
std::istringstream iss(color); std::istringstream iss(color);
iss >> std::hex >> color_value; iss >> std::hex >> color_value;
outcolor = irr::video::SColor(color_value); outcolor = irr::video::SColor(color_value);
outcolor.setAlpha(255); outcolor.setAlpha(255);
return true; return true;
} }

@ -297,8 +297,17 @@ private:
std::map<std::wstring,int> listbox_selections; std::map<std::wstring,int> listbox_selections;
} parserData; } parserData;
typedef struct {
bool key_up;
bool key_down;
bool key_enter;
bool key_escape;
} fs_key_pendig;
std::vector<video::ITexture *> m_Textures; std::vector<video::ITexture *> m_Textures;
fs_key_pendig current_keys_pending;
void parseElement(parserData* data,std::string element); void parseElement(parserData* data,std::string element);
void parseSize(parserData* data,std::string element); void parseSize(parserData* data,std::string element);

@ -389,7 +389,7 @@ public:
scene::IMesh *node_mesh = mapblock_mesh.getMesh(); scene::IMesh *node_mesh = mapblock_mesh.getMesh();
assert(node_mesh); assert(node_mesh);
video::SColor c(255, 255, 255, 255); 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)); c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source));
setMeshColor(node_mesh, c); setMeshColor(node_mesh, c);

@ -1069,10 +1069,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
/* /*
Convert MeshCollector to SMesh 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_bumpmapping = g_settings->getBool("enable_bumpmapping");
bool enable_shaders = g_settings->getBool("enable_shaders");
video::E_MATERIAL_TYPE shadermat1 = m_gamedef->getShaderSource()-> video::E_MATERIAL_TYPE shadermat1 = m_gamedef->getShaderSource()->
getShader("test_shader_1").material; getShader("test_shader_1").material;
video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()-> video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()->

@ -362,7 +362,7 @@ ShaderInfo generate_shader(std::string name, IrrlichtDevice *device,
Load shader programs Load shader programs
*/ */
void load_shaders(std::string name, SourceShaderCache *sourcecache, 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 &vertex_program, std::string &pixel_program,
std::string &geometry_program, bool &is_highlevel); 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 // 0 = off, 1 = assembly shaders only, 2 = highlevel or assembly
s32 enable_shaders = g_settings->getS32("enable_shaders"); bool enable_shaders = g_settings->getBool("enable_shaders");
if(enable_shaders <= 0) if(!enable_shaders)
return shaderinfo; return shaderinfo;
video::IVideoDriver* driver = device->getVideoDriver(); 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, 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 &vertex_program, std::string &pixel_program,
std::string &geometry_program, bool &is_highlevel) std::string &geometry_program, bool &is_highlevel)
{ {
@ -757,7 +757,7 @@ void load_shaders(std::string name, SourceShaderCache *sourcecache,
geometry_program = ""; geometry_program = "";
is_highlevel = false; is_highlevel = false;
if(enable_shaders >= 2){ if(enable_shaders){
// Look for high level shaders // Look for high level shaders
if(drivertype == video::EDT_DIRECT3D9){ if(drivertype == video::EDT_DIRECT3D9){
// Direct3D 9: HLSL // 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 // Look for assembly shaders
if(drivertype == video::EDT_DIRECT3D8){ if(drivertype == video::EDT_DIRECT3D8){
// Direct3D 8 assembly shaders // Direct3D 8 assembly shaders