Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix many formspec menu bugs
  • Loading branch information
sapier authored and kwolekr committed Jul 7, 2013
1 parent 7e73b7c commit 88d43af
Show file tree
Hide file tree
Showing 13 changed files with 374 additions and 113 deletions.
270 changes: 218 additions & 52 deletions builtin/mainmenu.lua

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions builtin/mainmenu_helper.lua
Expand Up @@ -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
Expand Down
19 changes: 12 additions & 7 deletions builtin/modmgr.lua
Expand Up @@ -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]
Expand Down
1 change: 1 addition & 0 deletions builtin/modstore.lua
Expand Up @@ -273,3 +273,4 @@ function modstore.get_details(modid)
modstore.details_cache[modid] = retval
return retval
end

25 changes: 23 additions & 2 deletions doc/lua_api.txt
Expand Up @@ -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
Expand All @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion src/defaultsettings.cpp
Expand Up @@ -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");

Expand Down
2 changes: 1 addition & 1 deletion src/environment.cpp
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/guiEngine.cpp
Expand Up @@ -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);
}
}

Expand Down
132 changes: 96 additions & 36 deletions src/guiFormSpecMenu.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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]);
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

11 changes: 10 additions & 1 deletion src/guiFormSpecMenu.h
Expand Up @@ -297,8 +297,17 @@ class GUIFormSpecMenu : public GUIModalMenu
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);
Expand All @@ -321,7 +330,7 @@ class GUIFormSpecMenu : public GUIModalMenu
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
Expand Down
2 changes: 1 addition & 1 deletion src/itemdef.cpp
Expand Up @@ -389,7 +389,7 @@ class CItemDefManager: public IWritableItemDefManager
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);

Expand Down
3 changes: 1 addition & 2 deletions src/mapblock_mesh.cpp
Expand Up @@ -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()->
Expand Down

0 comments on commit 88d43af

Please sign in to comment.