#include "constants.h"
#include "gamedef.h"
#include "keycode.h"
-#include "strfnd.h"
+#include "util/strfnd.h"
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include "util/hex.h"
#include "util/numeric.h"
#include "util/string.h" // for parseColorString()
+#include "irrlicht_changes/static_text.h"
#include "guiscalingfilter.h"
#if USE_FREETYPE && IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9
}
GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
+ JoystickController *joystick,
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
InventoryManager *invmgr, IGameDef *gamedef,
ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst,
m_text_dst(tdst),
m_formspec_version(0),
m_focused_element(""),
+ m_joystick(joystick),
+ current_field_enter_pending(""),
m_font(NULL),
m_remap_dbl_click(remap_dbl_click)
#ifdef __ANDROID__
return 0;
}
-static std::vector<std::string> split(const std::string &s, char delim)
+std::vector<std::string>* GUIFormSpecMenu::getDropDownValues(const std::string &name)
{
- std::vector<std::string> tokens;
-
- std::string current = "";
- bool last_was_escape = false;
- for (unsigned int i = 0; i < s.size(); i++) {
- char si = s.c_str()[i];
- if (last_was_escape) {
- current += '\\';
- current += si;
- last_was_escape = false;
- } else {
- if (si == delim) {
- tokens.push_back(current);
- current = "";
- last_was_escape = false;
- } else if (si == '\\') {
- last_was_escape = true;
- } else {
- current += si;
- last_was_escape = false;
- }
- }
+ for (u32 i = 0; i < m_dropdowns.size(); ++i) {
+ if (name == m_dropdowns[i].first.fname)
+ return &m_dropdowns[i].second;
}
- //push last element
- tokens.push_back(current);
-
- return tokens;
+ return NULL;
}
void GUIFormSpecMenu::parseSize(parserData* data,std::string element)
if (selected == "true")
fselected = true;
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
core::rect<s32> rect = core::rect<s32>(
pos.X, pos.Y + ((imgsize.Y/2) - m_btn_height),
if(!data->explicit_size)
warningstream<<"invalid use of button without a size[] element"<<std::endl;
- label = unescape_string(label);
-
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
FieldSpec spec(
name,
geom.X = stof(v_geom[0]) * (float)spacing.X;
geom.Y = stof(v_geom[1]) * (float)spacing.Y;
- if (parts.size() == 4) {
- m_clipbackground = is_yes(parts[3]);
- if (m_clipbackground) {
- pos.X = stoi(v_pos[0]); //acts as offset
- pos.Y = stoi(v_pos[1]); //acts as offset
- }
+ if (!data->explicit_size)
+ warningstream<<"invalid use of background without a size[] element"<<std::endl;
+
+ bool clip = false;
+ if (parts.size() == 4 && is_yes(parts[3])) {
+ pos.X = stoi(v_pos[0]); //acts as offset
+ pos.Y = stoi(v_pos[1]); //acts as offset
+ clip = true;
}
+ m_backgrounds.push_back(ImageDrawSpec(name, pos, geom, clip));
- if(!data->explicit_size)
- warningstream<<"invalid use of background without a size[] element"<<std::endl;
- m_backgrounds.push_back(ImageDrawSpec(name, pos, geom));
return;
}
errorstream<< "Invalid background element(" << parts.size() << "): '" << element << "'" << std::endl;
geom.X = stof(v_geom[0]) * (float)spacing.X;
geom.Y = stof(v_geom[1]) * (float)spacing.Y;
-
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
FieldSpec spec(
spec.ftype = f_Table;
for (unsigned int i = 0; i < items.size(); ++i) {
- items[i] = unescape_string(items[i]);
+ items[i] = unescape_enriched(unescape_string(items[i]));
}
//now really show table
spec.ftype = f_Table;
for (unsigned int i = 0; i < items.size(); ++i) {
- items[i] = unescape_string(items[i]);
+ items[i] = unescape_enriched(unescape_string(items[i]));
}
//now really show list
}
for (unsigned int i=0; i < items.size(); i++) {
- e->addItem(utf8_to_wide(items[i]).c_str());
+ e->addItem(unescape_enriched(unescape_string(
+ utf8_to_wide(items[i]))).c_str());
}
if (str_initial_selection != "")
e->setSelected(stoi(str_initial_selection.c_str())-1);
m_fields.push_back(spec);
+
+ m_dropdowns.push_back(std::pair<FieldSpec,
+ std::vector<std::string> >(spec, std::vector<std::string>()));
+ std::vector<std::string> &values = m_dropdowns.back().second;
+ for (unsigned int i = 0; i < items.size(); i++) {
+ values.push_back(unescape_string(items[i]));
+ }
+
return;
}
errorstream << "Invalid dropdown element(" << parts.size() << "): '"
{
std::vector<std::string> parts = split(element,';');
- if ((parts.size() == 4) ||
- ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION)))
+ if ((parts.size() == 4) || (parts.size() == 5) ||
+ ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
{
std::vector<std::string> v_pos = split(parts[0],',');
std::vector<std::string> v_geom = split(parts[1],',');
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
- label = unescape_string(label);
-
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
FieldSpec spec(
name,
int font_height = g_fontengine->getTextHeight();
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
- Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
}
e->setPasswordBox(true,L'*');
evt.KeyInput.Shift = 0;
evt.KeyInput.PressedDown = true;
e->OnEvent(evt);
+
+ if (parts.size() >= 5 && !is_yes(parts[4])) {
+ spec.close_on_enter = false;
+ }
+
m_fields.push_back(spec);
return;
}
if(m_form_src)
default_val = m_form_src->resolveText(default_val);
- default_val = unescape_string(default_val);
- label = unescape_string(label);
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
FieldSpec spec(
name,
wlabel,
- utf8_to_wide(default_val),
+ utf8_to_wide(unescape_string(default_val)),
258+m_fields.size()
);
if (name == "")
{
// 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);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, spec.fid);
}
else
{
int font_height = g_fontengine->getTextHeight();
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
- Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
}
}
+ if (parts.size() >= 4 && !is_yes(parts[3])) {
+ spec.close_on_enter = false;
+ }
+
m_fields.push_back(spec);
}
default_val = m_form_src->resolveText(default_val);
- default_val = unescape_string(default_val);
- label = unescape_string(label);
-
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
FieldSpec spec(
name,
wlabel,
- utf8_to_wide(default_val),
+ utf8_to_wide(unescape_string(default_val)),
258+m_fields.size()
);
if (name == "")
{
// 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);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, spec.fid);
}
else
{
int font_height = g_fontengine->getTextHeight();
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
- Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
}
}
+
+ if (parts.size() >= 6 && !is_yes(parts[5])) {
+ spec.close_on_enter = false;
+ }
+
m_fields.push_back(spec);
}
return;
}
- if ((parts.size() == 5) ||
- ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
+ if ((parts.size() == 5) || (parts.size() == 6) ||
+ ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION)))
{
parseTextArea(data,parts,type);
return;
if(!data->explicit_size)
warningstream<<"invalid use of label without a size[] element"<<std::endl;
- text = unescape_string(text);
std::vector<std::string> lines = split(text, '\n');
for (unsigned int i = 0; i != lines.size(); i++) {
// in the integer cases: 0.4 is not exactly
// representable in binary floating point.
s32 posy = pos.Y + ((float)i) * spacing.Y * 2.0 / 5.0;
- std::wstring wlabel = utf8_to_wide(lines[i]);
+ std::wstring wlabel = utf8_to_wide(unescape_string(lines[i]));
core::rect<s32> rect = core::rect<s32>(
pos.X, posy - m_btn_height,
pos.X + m_font->getDimension(wlabel.c_str()).Width,
258+m_fields.size()
);
gui::IGUIStaticText *e =
- Environment->addStaticText(spec.flabel.c_str(),
+ addStaticText(Environment, spec.flabel.c_str(),
rect, false, false, this, spec.fid);
e->setTextAlignment(gui::EGUIA_UPPERLEFT,
gui::EGUIA_CENTER);
((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
{
std::vector<std::string> v_pos = split(parts[0],',');
- std::wstring text = utf8_to_wide(unescape_string(parts[1]));
+ std::wstring text = unescape_enriched(
+ unescape_string(utf8_to_wide(parts[1])));
MY_CHECKPOS("vertlabel",1);
258+m_fields.size()
);
gui::IGUIStaticText *t =
- Environment->addStaticText(spec.flabel.c_str(), rect, false, false, this, spec.fid);
+ addStaticText(Environment, spec.flabel.c_str(), rect, false, false, this, spec.fid);
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
m_fields.push_back(spec);
return;
image_name = unescape_string(image_name);
pressed_image_name = unescape_string(pressed_image_name);
- label = unescape_string(label);
- std::wstring wlabel = utf8_to_wide(label);
+ std::wstring wlabel = utf8_to_wide(unescape_string(label));
FieldSpec spec(
name,
e->setNotClipped(true);
for (unsigned int i = 0; i < buttons.size(); i++) {
- e->addTab(utf8_to_wide(buttons[i]).c_str(), -1);
+ e->addTab(unescape_enriched(unescape_string(
+ utf8_to_wide(buttons[i]))).c_str(), -1);
}
if ((tab_index >= 0) &&
std::string name = parts[3];
std::string label = parts[4];
+ label = unescape_string(label);
+ item_name = unescape_string(item_name);
+
MY_CHECKPOS("itemimagebutton",0);
MY_CHECKGEOM("itemimagebutton",1);
m_default_tooltip_bgcolor,
m_default_tooltip_color);
- label = unescape_string(label);
FieldSpec spec(
name,
utf8_to_wide(label),
m_slotbordercolor = video::SColor(200,0,0,0);
m_slotborder = false;
- m_clipbackground = false;
// Add tooltip
{
assert(m_tooltip_element == NULL);
// 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 = addStaticText(Environment, L"",core::rect<s32>(0,0,110,18));
m_tooltip_element->enableOverrideColor(true);
m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor);
m_tooltip_element->setDrawBackground(true);
}
// Draw tooltip
- std::string tooltip_text = "";
- if (hovering && !m_selected_item)
- tooltip_text = item.getDefinition(m_gamedef->idef()).description;
- if (tooltip_text != "") {
- std::vector<std::string> tt_rows = str_split(tooltip_text, '\n');
+ std::wstring tooltip_text = L"";
+ if (hovering && !m_selected_item) {
+ tooltip_text = utf8_to_wide(item.getDefinition(m_gamedef->idef()).description);
+ }
+ if (tooltip_text != L"") {
+ std::vector<std::wstring> tt_rows = str_split(tooltip_text, L'\n');
m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor);
m_tooltip_element->setOverrideColor(m_default_tooltip_color);
m_tooltip_element->setVisible(true);
this->bringToFront(m_tooltip_element);
- m_tooltip_element->setText(utf8_to_wide(tooltip_text).c_str());
+ setStaticText(m_tooltip_element, tooltip_text.c_str());
s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height;
+#if IRRLICHT_VERSION_MAJOR <= 1 && IRRLICHT_VERSION_MINOR <= 8 && IRRLICHT_VERSION_REVISION < 2
s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5;
+#else
+ s32 tooltip_height = m_tooltip_element->getTextHeight() + 5;
+#endif
v2u32 screenSize = driver->getScreenSize();
int tooltip_offset_x = m_btn_height;
int tooltip_offset_y = m_btn_height;
// Image rectangle on screen
core::rect<s32> rect = imgrect + spec.pos;
- if (m_clipbackground) {
+ if (spec.clip) {
core::dimension2d<s32> absrec_size = AbsoluteRect.getSize();
rect = core::rect<s32>(AbsoluteRect.UpperLeftCorner.X - spec.pos.X,
AbsoluteRect.UpperLeftCorner.Y - spec.pos.Y,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
- }
- else {
+ } else {
errorstream << "GUIFormSpecMenu::drawMenu() Draw backgrounds unable to load texture:" << std::endl;
errorstream << "\t" << spec.name << std::endl;
}
Draw static text elements
*/
for (u32 i = 0; i < m_static_texts.size(); i++) {
- const StaticTextSpec &spec = m_static_texts[i];
+ const StaticTextSpec &spec = m_static_texts[i];
core::rect<s32> rect = spec.rect;
if (spec.parent_button && spec.parent_button->isPressed()) {
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
u32 delta = 0;
if (id == -1) {
m_old_tooltip_id = id;
- m_old_tooltip = "";
+ m_old_tooltip = L"";
} else {
if (id == m_old_tooltip_id) {
delta = porting::getDeltaMs(m_hovered_time, getTimeMs());
if (id != -1 && delta >= m_tooltip_show_delay) {
for(std::vector<FieldSpec>::iterator iter = m_fields.begin();
iter != m_fields.end(); ++iter) {
- if ( (iter->fid == id) && (m_tooltips[iter->fname].tooltip != "") ){
+ if (iter->fid == id && m_tooltips[iter->fname].tooltip != L"") {
if (m_old_tooltip != m_tooltips[iter->fname].tooltip) {
+ m_tooltip_element->setBackgroundColor(m_tooltips[iter->fname].bgcolor);
+ m_tooltip_element->setOverrideColor(m_tooltips[iter->fname].color);
m_old_tooltip = m_tooltips[iter->fname].tooltip;
- m_tooltip_element->setText(utf8_to_wide(m_tooltips[iter->fname].tooltip).c_str());
- std::vector<std::string> tt_rows = str_split(m_tooltips[iter->fname].tooltip, '\n');
+ setStaticText(m_tooltip_element, m_tooltips[iter->fname].tooltip.c_str());
+ std::vector<std::wstring> tt_rows = str_split(m_tooltips[iter->fname].tooltip, L'\n');
s32 tooltip_width = m_tooltip_element->getTextWidth() + m_btn_height;
s32 tooltip_height = m_tooltip_element->getTextHeight() * tt_rows.size() + 5;
int tooltip_offset_x = m_btn_height;
core::position2d<s32>(tooltip_x, tooltip_y),
core::dimension2d<s32>(tooltip_width, tooltip_height)));
}
- m_tooltip_element->setBackgroundColor(m_tooltips[iter->fname].bgcolor);
- m_tooltip_element->setOverrideColor(m_tooltips[iter->fname].color);
m_tooltip_element->setVisible(true);
this->bringToFront(m_tooltip_element);
break;
}
}
+ m_tooltip_element->draw();
+
/*
Draw dragged item stack
*/
current_keys_pending.key_enter = false;
}
+ if (!current_field_enter_pending.empty()) {
+ fields["key_enter_field"] = current_field_enter_pending;
+ current_field_enter_pending = "";
+ }
+
if (current_keys_pending.key_escape) {
fields["key_escape"] = "true";
current_keys_pending.key_escape = false;
}
s32 selected = e->getSelected();
if (selected >= 0) {
- fields[name] =
- wide_to_utf8(e->getItem(selected));
+ std::vector<std::string> *dropdown_values =
+ getDropDownValues(s.fname);
+ if (dropdown_values && selected < (s32)dropdown_values->size()) {
+ fields[name] = (*dropdown_values)[selected];
+ }
}
}
else if (s.ftype == f_TabHeader) {
core::position2d<s32>(x, y));
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
m_old_tooltip_id = -1;
- m_old_tooltip = "";
+ m_old_tooltip = L"";
}
if (!isChild(hovered,this)) {
if (DoubleClickDetection(event)) {
}
#endif
+ if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) {
+ /* TODO add a check like:
+ if (event.JoystickEvent != joystick_we_listen_for)
+ return false;
+ */
+ bool handled = m_joystick->handleEvent(event.JoystickEvent);
+ if (handled) {
+ if (m_joystick->wasKeyDown(KeyType::ESC)) {
+ tryClose();
+ } else if (m_joystick->wasKeyDown(KeyType::JUMP)) {
+ if (m_allowclose) {
+ acceptInput(quit_mode_accept);
+ quitMenu();
+ }
+ }
+ }
+ return handled;
+ }
+
return false;
}
return false;
}
+void GUIFormSpecMenu::tryClose()
+{
+ if (m_allowclose) {
+ doPause = false;
+ acceptInput(quit_mode_cancel);
+ quitMenu();
+ } else {
+ m_text_dst->gotText(L"MenuQuit");
+ }
+}
+
bool GUIFormSpecMenu::OnEvent(const SEvent& event)
{
if (event.EventType==EET_KEY_INPUT_EVENT) {
KeyPress kp(event.KeyInput);
if (event.KeyInput.PressedDown && ( (kp == EscapeKey) ||
(kp == getKeySetting("keymap_inventory")) || (kp == CancelKey))) {
- if (m_allowclose) {
- doPause = false;
- acceptInput(quit_mode_cancel);
- quitMenu();
- } else {
- m_text_dst->gotText(L"MenuQuit");
- }
+ tryClose();
return true;
} else if (m_client != NULL && event.KeyInput.PressedDown &&
(kp == getKeySetting("keymap_screenshot"))) {
if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
if (event.GUIEvent.Caller->getID() > 257) {
+ bool close_on_enter = true;
+ for (u32 i = 0; i < m_fields.size(); i++) {
+ FieldSpec &s = m_fields[i];
+ if (s.ftype == f_Unknown &&
+ s.fid == event.GUIEvent.Caller->getID()) {
+ current_field_enter_pending = s.fname;
+ close_on_enter = s.close_on_enter;
+ break;
+ }
+ }
- if (m_allowclose) {
+ if (m_allowclose && close_on_enter) {
+ current_keys_pending.key_enter = true;
acceptInput(quit_mode_accept);
quitMenu();
} else {