mirror of
https://github.com/minetest/minetest.git
synced 2024-12-03 13:03:45 +01:00
Implement formspec
This commit is contained in:
parent
c259f7c8bd
commit
506203345b
@ -1125,7 +1125,7 @@ minetest.register_node("default:sign_wall", {
|
|||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
--local n = minetest.env:get_node(pos)
|
--local n = minetest.env:get_node(pos)
|
||||||
local meta = minetest.env:get_meta(pos)
|
local meta = minetest.env:get_meta(pos)
|
||||||
meta:set_string("formspec", "hack:sign_text_input")
|
meta:set_string("formspec", "field[text;;${text}]")
|
||||||
meta:set_string("infotext", "\"\"")
|
meta:set_string("infotext", "\"\"")
|
||||||
end,
|
end,
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
|
@ -251,7 +251,7 @@ set(minetest_SRCS
|
|||||||
guiKeyChangeMenu.cpp
|
guiKeyChangeMenu.cpp
|
||||||
guiMessageMenu.cpp
|
guiMessageMenu.cpp
|
||||||
guiTextInputMenu.cpp
|
guiTextInputMenu.cpp
|
||||||
guiInventoryMenu.cpp
|
guiFormSpecMenu.cpp
|
||||||
guiPauseMenu.cpp
|
guiPauseMenu.cpp
|
||||||
guiPasswordChange.cpp
|
guiPasswordChange.cpp
|
||||||
guiDeathScreen.cpp
|
guiDeathScreen.cpp
|
||||||
|
@ -63,7 +63,7 @@ static bool content_nodemeta_deserialize_legacy_body(
|
|||||||
//meta->setString("infotext","\"${text}\"");
|
//meta->setString("infotext","\"${text}\"");
|
||||||
meta->setString("infotext",
|
meta->setString("infotext",
|
||||||
std::string("\"") + meta->getString("text") + "\"");
|
std::string("\"") + meta->getString("text") + "\"");
|
||||||
meta->setString("formspec","hack:sign_text_input");
|
meta->setString("formspec","field[text;;${text}]");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(id == NODEMETA_CHEST) // ChestNodeMetadata
|
else if(id == NODEMETA_CHEST) // ChestNodeMetadata
|
||||||
@ -77,7 +77,7 @@ static bool content_nodemeta_deserialize_legacy_body(
|
|||||||
}
|
}
|
||||||
assert(inv->getList("main") && !inv->getList("0"));
|
assert(inv->getList("main") && !inv->getList("0"));
|
||||||
|
|
||||||
meta->setString("formspec","invsize[8,9;]"
|
meta->setString("formspec","size[8,9]"
|
||||||
"list[current_name;main;0,0;8,4;]"
|
"list[current_name;main;0,0;8,4;]"
|
||||||
"list[current_player;main;0,5;8,4;]");
|
"list[current_player;main;0,5;8,4;]");
|
||||||
return false;
|
return false;
|
||||||
@ -94,7 +94,7 @@ static bool content_nodemeta_deserialize_legacy_body(
|
|||||||
}
|
}
|
||||||
assert(inv->getList("main") && !inv->getList("0"));
|
assert(inv->getList("main") && !inv->getList("0"));
|
||||||
|
|
||||||
meta->setString("formspec","invsize[8,9;]"
|
meta->setString("formspec","size[8,9]"
|
||||||
"list[current_name;main;0,0;8,4;]"
|
"list[current_name;main;0,0;8,4;]"
|
||||||
"list[current_player;main;0,5;8,4;]");
|
"list[current_player;main;0,5;8,4;]");
|
||||||
return false;
|
return false;
|
||||||
@ -115,7 +115,7 @@ static bool content_nodemeta_deserialize_legacy_body(
|
|||||||
is>>temp;
|
is>>temp;
|
||||||
meta->setString("src_time", ftos((float)temp/10));
|
meta->setString("src_time", ftos((float)temp/10));
|
||||||
|
|
||||||
meta->setString("formspec","invsize[8,9;]"
|
meta->setString("formspec","size[8,9]"
|
||||||
"list[current_name;fuel;2,3;1,1;]"
|
"list[current_name;fuel;2,3;1,1;]"
|
||||||
"list[current_name;src;2,1;1,1;]"
|
"list[current_name;src;2,1;1,1;]"
|
||||||
"list[current_name;dst;5,1;2,2;]"
|
"list[current_name;dst;5,1;2,2;]"
|
||||||
|
36
src/game.cpp
36
src/game.cpp
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "guiPauseMenu.h"
|
#include "guiPauseMenu.h"
|
||||||
#include "guiPasswordChange.h"
|
#include "guiPasswordChange.h"
|
||||||
#include "guiInventoryMenu.h"
|
#include "guiFormSpecMenu.h"
|
||||||
#include "guiTextInputMenu.h"
|
#include "guiTextInputMenu.h"
|
||||||
#include "guiDeathScreen.h"
|
#include "guiDeathScreen.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
@ -77,6 +77,10 @@ struct TextDestChat : public TextDest
|
|||||||
{
|
{
|
||||||
m_client->typeChatMessage(text);
|
m_client->typeChatMessage(text);
|
||||||
}
|
}
|
||||||
|
void gotText(std::map<std::string, std::string> fields)
|
||||||
|
{
|
||||||
|
m_client->typeChatMessage(narrow_to_wide(fields["text"]));
|
||||||
|
}
|
||||||
|
|
||||||
Client *m_client;
|
Client *m_client;
|
||||||
};
|
};
|
||||||
@ -88,15 +92,20 @@ struct TextDestNodeMetadata : public TextDest
|
|||||||
m_p = p;
|
m_p = p;
|
||||||
m_client = client;
|
m_client = client;
|
||||||
}
|
}
|
||||||
|
// This is deprecated I guess? -celeron55
|
||||||
void gotText(std::wstring text)
|
void gotText(std::wstring text)
|
||||||
{
|
{
|
||||||
std::string ntext = wide_to_narrow(text);
|
std::string ntext = wide_to_narrow(text);
|
||||||
infostream<<"Changing text of a sign node: "
|
infostream<<"Submitting 'text' field of node at ("<<m_p.X<<","
|
||||||
<<ntext<<std::endl;
|
<<m_p.Y<<","<<m_p.Z<<"): "<<ntext<<std::endl;
|
||||||
std::map<std::string, std::string> fields;
|
std::map<std::string, std::string> fields;
|
||||||
fields["text"] = ntext;
|
fields["text"] = ntext;
|
||||||
m_client->sendNodemetaFields(m_p, "", fields);
|
m_client->sendNodemetaFields(m_p, "", fields);
|
||||||
}
|
}
|
||||||
|
void gotText(std::map<std::string, std::string> fields)
|
||||||
|
{
|
||||||
|
m_client->sendNodemetaFields(m_p, "", fields);
|
||||||
|
}
|
||||||
|
|
||||||
v3s16 m_p;
|
v3s16 m_p;
|
||||||
Client *m_client;
|
Client *m_client;
|
||||||
@ -139,6 +148,13 @@ public:
|
|||||||
return "";
|
return "";
|
||||||
return meta->getString("formspec");
|
return meta->getString("formspec");
|
||||||
}
|
}
|
||||||
|
std::string resolveText(std::string str)
|
||||||
|
{
|
||||||
|
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||||
|
if(!meta)
|
||||||
|
return str;
|
||||||
|
return meta->resolveString(str);
|
||||||
|
}
|
||||||
|
|
||||||
ClientMap *m_map;
|
ClientMap *m_map;
|
||||||
v3s16 m_p;
|
v3s16 m_p;
|
||||||
@ -1479,8 +1495,8 @@ void the_game(
|
|||||||
infostream<<"the_game: "
|
infostream<<"the_game: "
|
||||||
<<"Launching inventory"<<std::endl;
|
<<"Launching inventory"<<std::endl;
|
||||||
|
|
||||||
GUIInventoryMenu *menu =
|
GUIFormSpecMenu *menu =
|
||||||
new GUIInventoryMenu(guienv, guiroot, -1,
|
new GUIFormSpecMenu(guienv, guiroot, -1,
|
||||||
&g_menumgr,
|
&g_menumgr,
|
||||||
&client, gamedef);
|
&client, gamedef);
|
||||||
|
|
||||||
@ -1490,7 +1506,7 @@ void the_game(
|
|||||||
PlayerInventoryFormSource *src = new PlayerInventoryFormSource(&client);
|
PlayerInventoryFormSource *src = new PlayerInventoryFormSource(&client);
|
||||||
assert(src);
|
assert(src);
|
||||||
menu->setFormSpec(src->getForm(), inventoryloc);
|
menu->setFormSpec(src->getForm(), inventoryloc);
|
||||||
menu->setFormSource(new PlayerInventoryFormSource(&client));
|
menu->setFormSource(src);
|
||||||
menu->drop();
|
menu->drop();
|
||||||
}
|
}
|
||||||
else if(input->wasKeyDown(EscapeKey))
|
else if(input->wasKeyDown(EscapeKey))
|
||||||
@ -2219,7 +2235,8 @@ void the_game(
|
|||||||
{
|
{
|
||||||
infostream<<"Ground right-clicked"<<std::endl;
|
infostream<<"Ground right-clicked"<<std::endl;
|
||||||
|
|
||||||
// sign special case, at least until formspec is properly implemented
|
// Sign special case, at least until formspec is properly implemented.
|
||||||
|
// Deprecated?
|
||||||
if(meta && meta->getString("formspec") == "hack:sign_text_input" && !random_input)
|
if(meta && meta->getString("formspec") == "hack:sign_text_input" && !random_input)
|
||||||
{
|
{
|
||||||
infostream<<"Launching metadata text input"<<std::endl;
|
infostream<<"Launching metadata text input"<<std::endl;
|
||||||
@ -2244,14 +2261,15 @@ void the_game(
|
|||||||
|
|
||||||
/* Create menu */
|
/* Create menu */
|
||||||
|
|
||||||
GUIInventoryMenu *menu =
|
GUIFormSpecMenu *menu =
|
||||||
new GUIInventoryMenu(guienv, guiroot, -1,
|
new GUIFormSpecMenu(guienv, guiroot, -1,
|
||||||
&g_menumgr,
|
&g_menumgr,
|
||||||
&client, gamedef);
|
&client, gamedef);
|
||||||
menu->setFormSpec(meta->getString("formspec"),
|
menu->setFormSpec(meta->getString("formspec"),
|
||||||
inventoryloc);
|
inventoryloc);
|
||||||
menu->setFormSource(new NodeMetadataFormSource(
|
menu->setFormSource(new NodeMetadataFormSource(
|
||||||
&client.getEnv().getClientMap(), nodepos));
|
&client.getEnv().getClientMap(), nodepos));
|
||||||
|
menu->setTextDest(new TextDestNodeMetadata(nodepos, &client));
|
||||||
menu->drop();
|
menu->drop();
|
||||||
}
|
}
|
||||||
// Otherwise report right click to server
|
// Otherwise report right click to server
|
||||||
|
@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "guiInventoryMenu.h"
|
#include "guiFormSpecMenu.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "keycode.h"
|
#include "keycode.h"
|
||||||
@ -33,6 +33,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
|
||||||
void drawItemStack(video::IVideoDriver *driver,
|
void drawItemStack(video::IVideoDriver *driver,
|
||||||
gui::IGUIFont *font,
|
gui::IGUIFont *font,
|
||||||
const ItemStack &item,
|
const ItemStack &item,
|
||||||
@ -120,10 +122,10 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GUIInventoryMenu
|
GUIFormSpecMenu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
|
GUIFormSpecMenu::GUIFormSpecMenu(gui::IGUIEnvironment* env,
|
||||||
gui::IGUIElement* parent, s32 id,
|
gui::IGUIElement* parent, s32 id,
|
||||||
IMenuManager *menumgr,
|
IMenuManager *menumgr,
|
||||||
InventoryManager *invmgr,
|
InventoryManager *invmgr,
|
||||||
@ -133,6 +135,7 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
|
|||||||
m_invmgr(invmgr),
|
m_invmgr(invmgr),
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
m_form_src(NULL),
|
m_form_src(NULL),
|
||||||
|
m_text_dst(NULL),
|
||||||
m_selected_item(NULL),
|
m_selected_item(NULL),
|
||||||
m_selected_amount(0),
|
m_selected_amount(0),
|
||||||
m_selected_dragging(false),
|
m_selected_dragging(false),
|
||||||
@ -140,7 +143,7 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIInventoryMenu::~GUIInventoryMenu()
|
GUIFormSpecMenu::~GUIFormSpecMenu()
|
||||||
{
|
{
|
||||||
removeChildren();
|
removeChildren();
|
||||||
|
|
||||||
@ -148,7 +151,7 @@ GUIInventoryMenu::~GUIInventoryMenu()
|
|||||||
delete m_form_src;
|
delete m_form_src;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::removeChildren()
|
void GUIFormSpecMenu::removeChildren()
|
||||||
{
|
{
|
||||||
const core::list<gui::IGUIElement*> &children = getChildren();
|
const core::list<gui::IGUIElement*> &children = getChildren();
|
||||||
core::list<gui::IGUIElement*> children_copy;
|
core::list<gui::IGUIElement*> children_copy;
|
||||||
@ -175,7 +178,7 @@ void GUIInventoryMenu::removeChildren()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||||
{
|
{
|
||||||
// Remove children
|
// Remove children
|
||||||
removeChildren();
|
removeChildren();
|
||||||
@ -183,24 +186,38 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
v2s32 size(100,100);
|
v2s32 size(100,100);
|
||||||
s32 helptext_h = 15;
|
s32 helptext_h = 15;
|
||||||
core::rect<s32> rect;
|
core::rect<s32> rect;
|
||||||
|
|
||||||
|
// Base position of contents of form
|
||||||
v2s32 basepos = getBasePos();
|
v2s32 basepos = getBasePos();
|
||||||
|
// State of basepos, 0 = not set, 1= set by formspec, 2 = set by size[] element
|
||||||
|
// Used to adjust form size automatically if needed
|
||||||
|
// A proceed button is added if there is no size[] element
|
||||||
|
int bp_set = 0;
|
||||||
|
|
||||||
/* Convert m_init_draw_spec to m_inventorylists */
|
/* Convert m_init_draw_spec to m_inventorylists */
|
||||||
|
|
||||||
m_inventorylists.clear();
|
m_inventorylists.clear();
|
||||||
m_images.clear();
|
m_images.clear();
|
||||||
|
m_fields.clear();
|
||||||
|
|
||||||
Strfnd f(m_formspec_string);
|
Strfnd f(m_formspec_string);
|
||||||
while(f.atend() == false)
|
while(f.atend() == false)
|
||||||
{
|
{
|
||||||
std::string type = trim(f.next("["));
|
std::string type = trim(f.next("["));
|
||||||
if(type == "invsize")
|
if(type == "invsize" || type == "size")
|
||||||
{
|
{
|
||||||
v2f invsize;
|
v2f invsize;
|
||||||
invsize.X = stof(f.next(","));
|
invsize.X = stof(f.next(","));
|
||||||
invsize.Y = stof(f.next(";"));
|
if(type == "size")
|
||||||
infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
|
{
|
||||||
f.next("]");
|
invsize.Y = stof(f.next("]"));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
invsize.Y = stof(f.next(";"));
|
||||||
|
errorstream<<"WARNING: invsize is deprecated, use size"<<std::endl;
|
||||||
|
f.next("]");
|
||||||
|
}
|
||||||
|
infostream<<"size ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
|
||||||
|
|
||||||
padding = v2s32(screensize.Y/40, screensize.Y/40);
|
padding = v2s32(screensize.Y/40, screensize.Y/40);
|
||||||
spacing = v2s32(screensize.Y/12, screensize.Y/13);
|
spacing = v2s32(screensize.Y/12, screensize.Y/13);
|
||||||
@ -218,6 +235,7 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
DesiredRect = rect;
|
DesiredRect = rect;
|
||||||
recalculateAbsolutePosition(false);
|
recalculateAbsolutePosition(false);
|
||||||
basepos = getBasePos();
|
basepos = getBasePos();
|
||||||
|
bp_set = 2;
|
||||||
}
|
}
|
||||||
else if(type == "list")
|
else if(type == "list")
|
||||||
{
|
{
|
||||||
@ -239,6 +257,8 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
<<", geom=("<<geom.X<<","<<geom.Y<<")"
|
<<", geom=("<<geom.X<<","<<geom.Y<<")"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
f.next("]");
|
f.next("]");
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
|
||||||
m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom));
|
m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom));
|
||||||
}
|
}
|
||||||
else if(type == "image")
|
else if(type == "image")
|
||||||
@ -254,8 +274,189 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
<<", pos=("<<pos.X<<","<<pos.Y<<")"
|
<<", pos=("<<pos.X<<","<<pos.Y<<")"
|
||||||
<<", geom=("<<geom.X<<","<<geom.Y<<")"
|
<<", geom=("<<geom.X<<","<<geom.Y<<")"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
|
||||||
m_images.push_back(ImageDrawSpec(name, pos, geom));
|
m_images.push_back(ImageDrawSpec(name, pos, geom));
|
||||||
}
|
}
|
||||||
|
else if(type == "field")
|
||||||
|
{
|
||||||
|
std::string fname = f.next(";");
|
||||||
|
std::string flabel = f.next(";");
|
||||||
|
|
||||||
|
if(fname.find(",") == std::string::npos && flabel.find(",") == std::string::npos)
|
||||||
|
{
|
||||||
|
if(!bp_set)
|
||||||
|
{
|
||||||
|
rect = core::rect<s32>(
|
||||||
|
screensize.X/2 - 580/2,
|
||||||
|
screensize.Y/2 - 300/2,
|
||||||
|
screensize.X/2 + 580/2,
|
||||||
|
screensize.Y/2 + 300/2
|
||||||
|
);
|
||||||
|
DesiredRect = rect;
|
||||||
|
recalculateAbsolutePosition(false);
|
||||||
|
basepos = getBasePos();
|
||||||
|
bp_set = 1;
|
||||||
|
}
|
||||||
|
else if(bp_set == 2)
|
||||||
|
errorstream<<"WARNING: invalid use of unpositioned field in inventory"<<std::endl;
|
||||||
|
|
||||||
|
v2s32 pos = basepos;
|
||||||
|
pos.Y = ((m_fields.size()+2)*60);
|
||||||
|
v2s32 size = DesiredRect.getSize();
|
||||||
|
rect = core::rect<s32>(size.X/2-150, pos.Y, (size.X/2-150)+300, pos.Y+30);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v2s32 pos;
|
||||||
|
pos.X = stof(fname.substr(0,fname.find(","))) * (float)spacing.X;
|
||||||
|
pos.Y = stof(fname.substr(fname.find(",")+1)) * (float)spacing.Y;
|
||||||
|
v2s32 geom;
|
||||||
|
geom.X = (stof(flabel.substr(0,flabel.find(","))) * (float)spacing.X)-(spacing.X-imgsize.X);
|
||||||
|
pos.Y += (stof(flabel.substr(flabel.find(",")+1)) * (float)imgsize.Y)/2;
|
||||||
|
|
||||||
|
rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15);
|
||||||
|
|
||||||
|
fname = f.next(";");
|
||||||
|
flabel = f.next(";");
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of positioned field without a size[] element"<<std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string odefault = f.next("]");
|
||||||
|
std::string fdefault;
|
||||||
|
|
||||||
|
// fdefault may contain a variable reference, which
|
||||||
|
// needs to be resolved from the node metadata
|
||||||
|
if(m_form_src)
|
||||||
|
fdefault = m_form_src->resolveText(odefault);
|
||||||
|
else
|
||||||
|
fdefault = odefault;
|
||||||
|
|
||||||
|
FieldSpec spec = FieldSpec(
|
||||||
|
narrow_to_wide(fname.c_str()),
|
||||||
|
narrow_to_wide(flabel.c_str()),
|
||||||
|
narrow_to_wide(fdefault.c_str()),
|
||||||
|
258+m_fields.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
// three cases: field and no label, label and no field, label and field
|
||||||
|
if (flabel == "")
|
||||||
|
{
|
||||||
|
spec.send = true;
|
||||||
|
gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
|
||||||
|
Environment->setFocus(e);
|
||||||
|
|
||||||
|
irr::SEvent evt;
|
||||||
|
evt.EventType = EET_KEY_INPUT_EVENT;
|
||||||
|
evt.KeyInput.Key = KEY_END;
|
||||||
|
evt.KeyInput.PressedDown = true;
|
||||||
|
e->OnEvent(evt);
|
||||||
|
}
|
||||||
|
else if (fname == "")
|
||||||
|
{
|
||||||
|
// set spec field id to 0, this stops submit searching for a value that isn't there
|
||||||
|
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spec.send = true;
|
||||||
|
gui::IGUIElement *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
|
||||||
|
Environment->setFocus(e);
|
||||||
|
rect.UpperLeftCorner.Y -= 15;
|
||||||
|
rect.LowerRightCorner.Y -= 15;
|
||||||
|
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
|
||||||
|
|
||||||
|
irr::SEvent evt;
|
||||||
|
evt.EventType = EET_KEY_INPUT_EVENT;
|
||||||
|
evt.KeyInput.Key = KEY_END;
|
||||||
|
evt.KeyInput.PressedDown = true;
|
||||||
|
e->OnEvent(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
}
|
||||||
|
else if(type == "label")
|
||||||
|
{
|
||||||
|
v2s32 pos;
|
||||||
|
pos.X = stof(f.next(",")) * (float)spacing.X;
|
||||||
|
pos.Y = stof(f.next(";")) * (float)spacing.Y;
|
||||||
|
|
||||||
|
rect = core::rect<s32>(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15));
|
||||||
|
|
||||||
|
std::string flabel = f.next("]");
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
|
||||||
|
|
||||||
|
FieldSpec spec = FieldSpec(
|
||||||
|
narrow_to_wide(""),
|
||||||
|
narrow_to_wide(flabel.c_str()),
|
||||||
|
narrow_to_wide(""),
|
||||||
|
258+m_fields.size()
|
||||||
|
);
|
||||||
|
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, spec.fid);
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
}
|
||||||
|
else if(type == "button")
|
||||||
|
{
|
||||||
|
v2s32 pos;
|
||||||
|
pos.X = stof(f.next(",")) * (float)spacing.X;
|
||||||
|
pos.Y = stof(f.next(";")) * (float)spacing.Y;
|
||||||
|
v2s32 geom;
|
||||||
|
geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
|
||||||
|
pos.Y += (stof(f.next(";")) * (float)imgsize.Y)/2;
|
||||||
|
|
||||||
|
rect = core::rect<s32>(pos.X, pos.Y-15, pos.X+geom.X, pos.Y+15);
|
||||||
|
|
||||||
|
std::string fname = f.next(";");
|
||||||
|
std::string flabel = f.next("]");
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
|
||||||
|
|
||||||
|
FieldSpec spec = FieldSpec(
|
||||||
|
narrow_to_wide(fname.c_str()),
|
||||||
|
narrow_to_wide(flabel.c_str()),
|
||||||
|
narrow_to_wide(""),
|
||||||
|
258+m_fields.size()
|
||||||
|
);
|
||||||
|
spec.is_button = true;
|
||||||
|
Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
}
|
||||||
|
else if(type == "image_button")
|
||||||
|
{
|
||||||
|
v2s32 pos;
|
||||||
|
pos.X = stof(f.next(",")) * (float)spacing.X;
|
||||||
|
pos.Y = stof(f.next(";")) * (float)spacing.Y;
|
||||||
|
v2s32 geom;
|
||||||
|
geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
|
||||||
|
geom.Y = (stof(f.next(";")) * (float)spacing.Y)-(spacing.Y-imgsize.Y);
|
||||||
|
|
||||||
|
rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
|
||||||
|
|
||||||
|
std::string fimage = f.next(";");
|
||||||
|
std::string fname = f.next(";");
|
||||||
|
std::string flabel = f.next("]");
|
||||||
|
if(bp_set != 2)
|
||||||
|
errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl;
|
||||||
|
|
||||||
|
FieldSpec spec = FieldSpec(
|
||||||
|
narrow_to_wide(fname.c_str()),
|
||||||
|
narrow_to_wide(flabel.c_str()),
|
||||||
|
narrow_to_wide(fimage.c_str()),
|
||||||
|
258+m_fields.size()
|
||||||
|
);
|
||||||
|
spec.is_button = true;
|
||||||
|
|
||||||
|
video::ITexture *texture = m_gamedef->tsrc()->getTextureRaw(fimage);
|
||||||
|
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
|
||||||
|
e->setImage(texture);
|
||||||
|
e->setPressedImage(texture);
|
||||||
|
e->setScaleImage(true);
|
||||||
|
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ignore others
|
// Ignore others
|
||||||
@ -265,16 +466,44 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add children
|
// If there's inventory, put the usage string at the bottom
|
||||||
|
if (m_inventorylists.size())
|
||||||
{
|
{
|
||||||
|
changeCtype("");
|
||||||
core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
|
core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
|
||||||
rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
|
rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
|
||||||
size.Y-rect.getHeight()-5);
|
size.Y-rect.getHeight()-5);
|
||||||
const wchar_t *text =
|
const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item");
|
||||||
L"Left click: Move all items, Right click: Move single item";
|
|
||||||
Environment->addStaticText(text, rect, false, true, this, 256);
|
Environment->addStaticText(text, rect, false, true, this, 256);
|
||||||
|
changeCtype("C");
|
||||||
|
}
|
||||||
|
// If there's fields, add a Proceed button
|
||||||
|
if (m_fields.size() && bp_set != 2)
|
||||||
|
{
|
||||||
|
// if the size wasn't set by an invsize[] or size[] adjust it now to fit all the fields
|
||||||
|
rect = core::rect<s32>(
|
||||||
|
screensize.X/2 - 580/2,
|
||||||
|
screensize.Y/2 - 300/2,
|
||||||
|
screensize.X/2 + 580/2,
|
||||||
|
screensize.Y/2 + 240/2+(m_fields.size()*60)
|
||||||
|
);
|
||||||
|
DesiredRect = rect;
|
||||||
|
recalculateAbsolutePosition(false);
|
||||||
|
basepos = getBasePos();
|
||||||
|
|
||||||
// Add tooltip
|
changeCtype("");
|
||||||
|
{
|
||||||
|
v2s32 pos = basepos;
|
||||||
|
pos.Y = ((m_fields.size()+2)*60);
|
||||||
|
|
||||||
|
v2s32 size = DesiredRect.getSize();
|
||||||
|
rect = core::rect<s32>(size.X/2-70, pos.Y, (size.X/2-70)+140, pos.Y+30);
|
||||||
|
Environment->addButton(rect, this, 257, wgettext("Proceed"));
|
||||||
|
}
|
||||||
|
changeCtype("C");
|
||||||
|
}
|
||||||
|
// Add tooltip
|
||||||
|
{
|
||||||
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
|
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
|
||||||
m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18));
|
m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18));
|
||||||
m_tooltip_element->enableOverrideColor(true);
|
m_tooltip_element->enableOverrideColor(true);
|
||||||
@ -287,7 +516,7 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
|
GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
|
||||||
{
|
{
|
||||||
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
|
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
|
||||||
|
|
||||||
@ -311,7 +540,7 @@ GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
|
|||||||
return ItemSpec(InventoryLocation(), "", -1);
|
return ItemSpec(InventoryLocation(), "", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
|
void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
|
||||||
{
|
{
|
||||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||||
|
|
||||||
@ -323,7 +552,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
|
|||||||
|
|
||||||
Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
|
Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
|
||||||
if(!inv){
|
if(!inv){
|
||||||
infostream<<"GUIInventoryMenu::drawList(): WARNING: "
|
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
|
||||||
<<"The inventory location "
|
<<"The inventory location "
|
||||||
<<"\""<<s.inventoryloc.dump()<<"\" doesn't exist"
|
<<"\""<<s.inventoryloc.dump()<<"\" doesn't exist"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
@ -331,7 +560,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
|
|||||||
}
|
}
|
||||||
InventoryList *ilist = inv->getList(s.listname);
|
InventoryList *ilist = inv->getList(s.listname);
|
||||||
if(!ilist){
|
if(!ilist){
|
||||||
infostream<<"GUIInventoryMenu::drawList(): WARNING: "
|
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
|
||||||
<<"The inventory list \""<<s.listname<<"\" @ \""
|
<<"The inventory list \""<<s.listname<<"\" @ \""
|
||||||
<<s.inventoryloc.dump()<<"\" doesn't exist"
|
<<s.inventoryloc.dump()<<"\" doesn't exist"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
@ -404,7 +633,7 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s, int phase)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::drawSelectedItem()
|
void GUIFormSpecMenu::drawSelectedItem()
|
||||||
{
|
{
|
||||||
if(!m_selected_item)
|
if(!m_selected_item)
|
||||||
return;
|
return;
|
||||||
@ -429,7 +658,7 @@ void GUIInventoryMenu::drawSelectedItem()
|
|||||||
drawItemStack(driver, font, stack, rect, NULL, m_gamedef);
|
drawItemStack(driver, font, stack, rect, NULL, m_gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::drawMenu()
|
void GUIFormSpecMenu::drawMenu()
|
||||||
{
|
{
|
||||||
if(m_form_src){
|
if(m_form_src){
|
||||||
std::string newform = m_form_src->getForm();
|
std::string newform = m_form_src->getForm();
|
||||||
@ -491,7 +720,7 @@ void GUIInventoryMenu::drawMenu()
|
|||||||
gui::IGUIElement::draw();
|
gui::IGUIElement::draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIInventoryMenu::updateSelectedItem()
|
void GUIFormSpecMenu::updateSelectedItem()
|
||||||
{
|
{
|
||||||
// If the selected stack has become empty for some reason, deselect it.
|
// If the selected stack has become empty for some reason, deselect it.
|
||||||
// If the selected stack has become smaller, adjust m_selected_amount.
|
// If the selected stack has become smaller, adjust m_selected_amount.
|
||||||
@ -558,7 +787,38 @@ void GUIInventoryMenu::updateSelectedItem()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUIInventoryMenu::OnEvent(const SEvent& event)
|
void GUIFormSpecMenu::acceptInput()
|
||||||
|
{
|
||||||
|
if(m_text_dst)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> fields;
|
||||||
|
gui::IGUIElement *e;
|
||||||
|
for(u32 i=0; i<m_fields.size(); i++)
|
||||||
|
{
|
||||||
|
const FieldSpec &s = m_fields[i];
|
||||||
|
if(s.send)
|
||||||
|
{
|
||||||
|
if(s.is_button)
|
||||||
|
{
|
||||||
|
fields[wide_to_narrow(s.fname.c_str())] = wide_to_narrow(s.flabel.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = getElementFromId(s.fid);
|
||||||
|
if(e != NULL)
|
||||||
|
{
|
||||||
|
fields[wide_to_narrow(s.fname.c_str())] = wide_to_narrow(e->getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_text_dst->gotText(fields);
|
||||||
|
delete m_text_dst;
|
||||||
|
m_text_dst = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||||
{
|
{
|
||||||
if(event.EventType==EET_KEY_INPUT_EVENT)
|
if(event.EventType==EET_KEY_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
@ -569,6 +829,12 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
|
|||||||
quitMenu();
|
quitMenu();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
|
||||||
|
{
|
||||||
|
acceptInput();
|
||||||
|
quitMenu();
|
||||||
|
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)
|
||||||
@ -860,7 +1126,7 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
|
|||||||
{
|
{
|
||||||
if(!canTakeFocus(event.GUIEvent.Element))
|
if(!canTakeFocus(event.GUIEvent.Element))
|
||||||
{
|
{
|
||||||
infostream<<"GUIInventoryMenu: Not allowing focus change."
|
infostream<<"GUIFormSpecMenu: Not allowing focus change."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
// Returning true disables focus change
|
// Returning true disables focus change
|
||||||
return true;
|
return true;
|
||||||
@ -868,15 +1134,38 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
|
|||||||
}
|
}
|
||||||
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
|
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
|
||||||
{
|
{
|
||||||
/*switch(event.GUIEvent.Caller->getID())
|
switch(event.GUIEvent.Caller->getID())
|
||||||
{
|
{
|
||||||
case 256: // continue
|
case 257:
|
||||||
setVisible(false);
|
acceptInput();
|
||||||
break;
|
quitMenu();
|
||||||
case 257: // exit
|
// quitMenu deallocates menu
|
||||||
dev->closeDevice();
|
return true;
|
||||||
break;
|
}
|
||||||
}*/
|
// find the element that was clicked
|
||||||
|
for(u32 i=0; i<m_fields.size(); i++)
|
||||||
|
{
|
||||||
|
FieldSpec &s = m_fields[i];
|
||||||
|
// if its a button, set the send field so
|
||||||
|
// lua knows which button was pressed
|
||||||
|
if (s.is_button && s.fid == event.GUIEvent.Caller->getID())
|
||||||
|
{
|
||||||
|
s.send = true;
|
||||||
|
acceptInput();
|
||||||
|
quitMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
|
||||||
|
{
|
||||||
|
if(event.GUIEvent.Caller->getID() > 257)
|
||||||
|
{
|
||||||
|
acceptInput();
|
||||||
|
quitMenu();
|
||||||
|
// quitMenu deallocates menu
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,11 +29,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
class IGameDef;
|
class IGameDef;
|
||||||
class InventoryManager;
|
class InventoryManager;
|
||||||
|
|
||||||
|
struct TextDest
|
||||||
|
{
|
||||||
|
virtual ~TextDest() {};
|
||||||
|
// This is deprecated I guess? -celeron55
|
||||||
|
virtual void gotText(std::wstring text) = 0;
|
||||||
|
virtual void gotText(std::map<std::string, std::string> fields) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class IFormSource
|
class IFormSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IFormSource(){}
|
virtual ~IFormSource(){}
|
||||||
virtual std::string getForm() = 0;
|
virtual std::string getForm() = 0;
|
||||||
|
// Fill in variables in field text
|
||||||
|
virtual std::string resolveText(std::string str){ return str; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void drawItemStack(video::IVideoDriver *driver,
|
void drawItemStack(video::IVideoDriver *driver,
|
||||||
@ -43,7 +53,7 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
const core::rect<s32> *clip,
|
const core::rect<s32> *clip,
|
||||||
IGameDef *gamedef);
|
IGameDef *gamedef);
|
||||||
|
|
||||||
class GUIInventoryMenu : public GUIModalMenu
|
class GUIFormSpecMenu : public GUIModalMenu
|
||||||
{
|
{
|
||||||
struct ItemSpec
|
struct ItemSpec
|
||||||
{
|
{
|
||||||
@ -106,15 +116,37 @@ class GUIInventoryMenu : public GUIModalMenu
|
|||||||
v2s32 pos;
|
v2s32 pos;
|
||||||
v2s32 geom;
|
v2s32 geom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FieldSpec
|
||||||
|
{
|
||||||
|
FieldSpec()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
FieldSpec(const std::wstring name, const std::wstring label, const std::wstring fdeflt, int id):
|
||||||
|
fname(name),
|
||||||
|
flabel(label),
|
||||||
|
fdefault(fdeflt),
|
||||||
|
fid(id)
|
||||||
|
{
|
||||||
|
send = false;
|
||||||
|
is_button = false;
|
||||||
|
}
|
||||||
|
std::wstring fname;
|
||||||
|
std::wstring flabel;
|
||||||
|
std::wstring fdefault;
|
||||||
|
int fid;
|
||||||
|
bool send;
|
||||||
|
bool is_button;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GUIInventoryMenu(gui::IGUIEnvironment* env,
|
GUIFormSpecMenu(gui::IGUIEnvironment* env,
|
||||||
gui::IGUIElement* parent, s32 id,
|
gui::IGUIElement* parent, s32 id,
|
||||||
IMenuManager *menumgr,
|
IMenuManager *menumgr,
|
||||||
InventoryManager *invmgr,
|
InventoryManager *invmgr,
|
||||||
IGameDef *gamedef
|
IGameDef *gamedef
|
||||||
);
|
);
|
||||||
~GUIInventoryMenu();
|
~GUIFormSpecMenu();
|
||||||
|
|
||||||
void setFormSpec(const std::string &formspec_string,
|
void setFormSpec(const std::string &formspec_string,
|
||||||
InventoryLocation current_inventory_location)
|
InventoryLocation current_inventory_location)
|
||||||
@ -124,12 +156,18 @@ public:
|
|||||||
regenerateGui(m_screensize_old);
|
regenerateGui(m_screensize_old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// form_src is deleted by this GUIInventoryMenu
|
// form_src is deleted by this GUIFormSpecMenu
|
||||||
void setFormSource(IFormSource *form_src)
|
void setFormSource(IFormSource *form_src)
|
||||||
{
|
{
|
||||||
m_form_src = form_src;
|
m_form_src = form_src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// text_dst is deleted by this GUIFormSpecMenu
|
||||||
|
void setTextDest(TextDest *text_dst)
|
||||||
|
{
|
||||||
|
m_text_dst = text_dst;
|
||||||
|
}
|
||||||
|
|
||||||
void removeChildren();
|
void removeChildren();
|
||||||
/*
|
/*
|
||||||
Remove and re-add (or reposition) stuff
|
Remove and re-add (or reposition) stuff
|
||||||
@ -142,6 +180,7 @@ public:
|
|||||||
void drawMenu();
|
void drawMenu();
|
||||||
void updateSelectedItem();
|
void updateSelectedItem();
|
||||||
|
|
||||||
|
void acceptInput();
|
||||||
bool OnEvent(const SEvent& event);
|
bool OnEvent(const SEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -160,9 +199,11 @@ protected:
|
|||||||
std::string m_formspec_string;
|
std::string m_formspec_string;
|
||||||
InventoryLocation m_current_inventory_location;
|
InventoryLocation m_current_inventory_location;
|
||||||
IFormSource *m_form_src;
|
IFormSource *m_form_src;
|
||||||
|
TextDest *m_text_dst;
|
||||||
|
|
||||||
core::array<ListDrawSpec> m_inventorylists;
|
core::array<ListDrawSpec> m_inventorylists;
|
||||||
core::array<ImageDrawSpec> m_images;
|
core::array<ImageDrawSpec> m_images;
|
||||||
|
core::array<FieldSpec> m_fields;
|
||||||
|
|
||||||
ItemSpec *m_selected_item;
|
ItemSpec *m_selected_item;
|
||||||
u32 m_selected_amount;
|
u32 m_selected_amount;
|
@ -22,14 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "modalMenu.h"
|
#include "modalMenu.h"
|
||||||
|
#include "guiFormSpecMenu.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct TextDest
|
|
||||||
{
|
|
||||||
virtual void gotText(std::wstring text) = 0;
|
|
||||||
virtual ~TextDest() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
class GUITextInputMenu : public GUIModalMenu
|
class GUITextInputMenu : public GUIModalMenu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
i = m_stringvars.find(name);
|
i = m_stringvars.find(name);
|
||||||
if(i == m_stringvars.end())
|
if(i == m_stringvars.end())
|
||||||
return "";
|
return "";
|
||||||
return i->second;
|
return resolveString(i->second);
|
||||||
}
|
}
|
||||||
void setString(const std::string &name, const std::string &var)
|
void setString(const std::string &name, const std::string &var)
|
||||||
{
|
{
|
||||||
@ -64,6 +64,13 @@ public:
|
|||||||
else
|
else
|
||||||
m_stringvars[name] = var;
|
m_stringvars[name] = var;
|
||||||
}
|
}
|
||||||
|
// support variable names in values
|
||||||
|
std::string resolveString(const std::string &str) const
|
||||||
|
{
|
||||||
|
if(str.substr(0,2) == "${" && str[str.length()-1] == '}')
|
||||||
|
return resolveString(getString(str.substr(2,str.length()-3)));
|
||||||
|
return str;
|
||||||
|
}
|
||||||
std::map<std::string, std::string> getStrings() const
|
std::map<std::string, std::string> getStrings() const
|
||||||
{
|
{
|
||||||
return m_stringvars;
|
return m_stringvars;
|
||||||
|
Loading…
Reference in New Issue
Block a user