Skip to content
Snippets Groups Projects
Commit 8548bb75 authored by Kahrl's avatar Kahrl
Browse files

GUIFormSpecMenu focus fixes

parent 72b9b0fe
No related branches found
No related tags found
No related merge requests found
......@@ -329,6 +329,8 @@ function modmgr.render_modlist(render_list)
if retval ~= "" then
retval = retval ..","
end
local color = ""
if v.is_modpack then
local rawlist = filterlist.get_raw_list(render_list)
......@@ -343,19 +345,21 @@ function modmgr.render_modlist(render_list)
end
if all_enabled == false then
retval = retval .. mt_color_grey
color = mt_color_grey
else
retval = retval .. mt_color_dark_green
color = mt_color_dark_green
end
end
if v.typ == "game_mod" then
retval = retval .. mt_color_blue
color = mt_color_blue
else
if v.enabled then
retval = retval .. mt_color_green
color = mt_color_green
end
end
retval = retval .. color
if v.modpack ~= nil then
retval = retval .. " "
end
......@@ -401,7 +405,7 @@ function modmgr.dialog_configure_world()
"button[9.25,6.35;2,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" ..
"button[7.4,6.35;2,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]"
if mod ~= nil and mod.name ~= "" then
if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then
if mod.is_modpack then
local rawlist = filterlist.get_raw_list(modmgr.modlist)
......@@ -662,57 +666,23 @@ function modmgr.handle_configure_world_buttons(fields)
modmgr.world_config_selected_mod = event.index
if event.typ == "DCL" then
local mod = filterlist.get_list(modmgr.modlist)[event.index]
if mod.typ == "game_mod" then
return nil
end
if not mod.is_modpack then
mod.enabled = not mod.enabled
else
local list = filterlist.get_raw_list(modmgr.modlist)
local toset = nil
for i=1,#list,1 do
if list[i].modpack == mod.name then
if toset == nil then
toset = not list[i].enabled
end
list[i].enabled = toset
end
end
end
modmgr.world_config_enable_mod(nil)
end
end
if fields["key_enter"] ~= nil then
modmgr.world_config_enable_mod(nil)
end
if fields["cb_mod_enable"] ~= nil then
local mod = filterlist.get_list(modmgr.modlist)
[engine.get_textlist_index("world_config_modlist")]
if fields["cb_mod_enable"] == "true" then
mod.enabled = true
else
mod.enabled = false
end
local toset = (fields["cb_mod_enable"] == "true")
modmgr.world_config_enable_mod(toset)
end
if fields["btn_mp_enable"] ~= nil or
fields["btn_mp_disable"] then
local mod = filterlist.get_list(modmgr.modlist)
[engine.get_textlist_index("world_config_modlist")]
local toset=false
if fields["btn_mp_enable"] ~= nil then
toset = true
end
local list = filterlist.get_raw_list(modmgr.modlist)
for i=1,#list,1 do
if list[i].modpack == mod.name then
list[i].enabled = toset
end
end
local toset = (fields["btn_mp_enable"] ~= nil)
modmgr.world_config_enable_mod(toset)
end
if fields["cb_hide_gamemods"] ~= nil then
......@@ -818,6 +788,31 @@ function modmgr.handle_configure_world_buttons(fields)
return nil
end
--------------------------------------------------------------------------------
function modmgr.world_config_enable_mod(toset)
local mod = filterlist.get_list(modmgr.modlist)
[engine.get_textlist_index("world_config_modlist")]
if mod.typ == "game_mod" then
-- game mods can't be enabled or disabled
elseif not mod.is_modpack then
if toset == nil then
mod.enabled = not mod.enabled
else
mod.enabled = toset
end
else
local list = filterlist.get_raw_list(modmgr.modlist)
for i=1,#list,1 do
if list[i].modpack == mod.name then
if toset == nil then
toset = not list[i].enabled
end
list[i].enabled = toset
end
end
end
end
--------------------------------------------------------------------------------
function modmgr.handle_delete_mod_buttons(fields)
local mod = filterlist.get_list(modmgr.global_mods)[modmgr.selected_mod]
......
......@@ -131,6 +131,81 @@ void GUIFormSpecMenu::removeChildren()
}
}
void GUIFormSpecMenu::setInitialFocus()
{
// Set initial focus according to following order of precedence:
// 1. first empty editbox
// 2. first editbox
// 3. first listbox
// 4. last button
// 5. first focusable (not statictext, not tabheader)
// 6. first child element
core::list<gui::IGUIElement*> children = getChildren();
// in case "children" contains any NULL elements, remove them
for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
it != children.end();) {
if (*it)
++it;
else
it = children.erase(it);
}
// 1. first empty editbox
for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
it != children.end(); ++it) {
if ((*it)->getType() == gui::EGUIET_EDIT_BOX
&& (*it)->getText()[0] == 0) {
Environment->setFocus(*it);
return;
}
}
// 2. first editbox
for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
it != children.end(); ++it) {
if ((*it)->getType() == gui::EGUIET_EDIT_BOX) {
Environment->setFocus(*it);
return;
}
}
// 3. first listbox
for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
it != children.end(); ++it) {
if ((*it)->getType() == gui::EGUIET_LIST_BOX) {
Environment->setFocus(*it);
return;
}
}
// 4. last button
for (core::list<gui::IGUIElement*>::Iterator it = children.getLast();
it != children.end(); --it) {
if ((*it)->getType() == gui::EGUIET_BUTTON) {
Environment->setFocus(*it);
return;
}
}
// 5. first focusable (not statictext, not tabheader)
for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
it != children.end(); ++it) {
if ((*it)->getType() != gui::EGUIET_STATIC_TEXT &&
(*it)->getType() != gui::EGUIET_TAB_CONTROL) {
Environment->setFocus(*it);
return;
}
}
// 6. first child element
if (children.empty())
Environment->setFocus(this);
else
Environment->setFocus(*(children.begin()));
}
int GUIFormSpecMenu::getListboxIndex(std::string listboxname) {
std::wstring wlistboxname = narrow_to_wide(listboxname.c_str());
......@@ -387,6 +462,11 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element) {
spec.flabel = wlabel; //Needed for displaying text on MSVC
gui::IGUICheckBox* e = Environment->addCheckBox(fselected, rect, this,
spec.fid, spec.flabel.c_str());
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
m_checkboxes.push_back(std::pair<FieldSpec,gui::IGUICheckBox*>(spec,e));
m_fields.push_back(spec);
return;
......@@ -503,7 +583,13 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,std::stri
if(type == "button_exit")
spec.is_exit = true;
Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
gui::IGUIButton* e = Environment->addButton(rect, this, spec.fid,
spec.flabel.c_str());
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
m_fields.push_back(spec);
return;
}
......@@ -582,9 +668,8 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) {
//now really show list
gui::IGUIListBox *e = Environment->addListBox(rect, this,spec.fid);
//don't reset if we already have a user specified selection
if (data->listbox_selections.find(fname_w) == data->listbox_selections.end()) {
e->setAutoScrollEnabled(false);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
if (str_transparent == "false")
......@@ -670,10 +755,9 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element) {
//now really show list
gui::IGUIComboBox *e = Environment->addComboBox(rect, this,spec.fid);
//don't reset if we already have a user specified selection
//if (data->combobox_selections.find(fname_w) == data->listbox_selections.end()) {
// e->setAutoScrollEnabled(false);
//}
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
for (unsigned int i=0; i < items.size(); i++) {
e->addItem(narrow_to_wide(items[i]).c_str());
......@@ -732,7 +816,10 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element) {
spec.send = true;
gui::IGUIEditBox * e = Environment->addEditBox(0, rect, true, this, spec.fid);
Environment->setFocus(e);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
if (label.length() > 1)
{
......@@ -811,7 +898,10 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,std::vector<std::string>
{
spec.send = true;
gui::IGUIEditBox *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
Environment->setFocus(e);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
irr::SEvent evt;
evt.EventType = EET_KEY_INPUT_EVENT;
......@@ -894,7 +984,10 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,std::vector<std::string>& p
{
spec.send = true;
gui::IGUIEditBox *e = Environment->addEditBox(spec.fdefault.c_str(), rect, true, this, spec.fid);
Environment->setFocus(e);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
if (type == "textarea")
{
......@@ -1091,6 +1184,11 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,std:
pressed_texture = texture;
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
e->setUseAlphaChannel(true);
e->setImage(texture);
e->setPressedImage(pressed_texture);
......@@ -1146,6 +1244,10 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element) {
gui::IGUITabControl *e = Environment->addTabControl(rect,this,show_background,show_border,spec.fid);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
e->setNotClipped(true);
for (unsigned int i=0; i< buttons.size(); i++) {
......@@ -1213,6 +1315,11 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
);
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
}
e->setUseAlphaChannel(true);
e->setImage(texture);
e->setPressedImage(texture);
......@@ -1400,6 +1507,21 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
}
//preserve focus
gui::IGUIElement *focused_element = Environment->getFocus();
if (focused_element && focused_element->getParent() == this) {
s32 focused_id = focused_element->getID();
if (focused_id > 257) {
for (u32 i=0; i<m_fields.size(); i++) {
if (m_fields[i].fid == focused_id) {
mydata.focused_fieldname =
m_fields[i].fname;
break;
}
}
}
}
// Remove children
removeChildren();
......@@ -1485,6 +1607,13 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
m_tooltip_element->setWordWrap(false);
}
//set initial focus if parser didn't set it
focused_element = Environment->getFocus();
if (!focused_element
|| !isMyChild(focused_element)
|| focused_element->getType() == gui::EGUIET_TAB_CONTROL)
setInitialFocus();
}
GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
......@@ -2041,6 +2170,41 @@ void GUIFormSpecMenu::acceptInput()
}
}
bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
{
// Fix Esc/Return key being eaten by checkboxen and listboxen
if(event.EventType==EET_KEY_INPUT_EVENT)
{
KeyPress kp(event.KeyInput);
if (kp == EscapeKey || kp == getKeySetting("keymap_inventory")
|| event.KeyInput.Key==KEY_RETURN)
{
gui::IGUIElement *focused = Environment->getFocus();
if (focused && isMyChild(focused) &&
(focused->getType() == gui::EGUIET_LIST_BOX ||
focused->getType() == gui::EGUIET_CHECK_BOX)) {
OnEvent(event);
return true;
}
}
}
// Mouse wheel events: send to hovered element instead of focused
if(event.EventType==EET_MOUSE_INPUT_EVENT
&& event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
s32 x = event.MouseInput.X;
s32 y = event.MouseInput.Y;
gui::IGUIElement *hovered =
Environment->getRootGUIElement()->getElementFromPoint(
core::position2d<s32>(x, y));
if (hovered && isMyChild(hovered)) {
hovered->OnEvent(event);
return true;
}
}
return false;
}
bool GUIFormSpecMenu::OnEvent(const SEvent& event)
{
if(event.EventType==EET_KEY_INPUT_EVENT)
......@@ -2391,8 +2555,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
s.send = true;
acceptInput();
s.send = false;
// Restore focus to the full form
Environment->setFocus(this);
return true;
}
}
......@@ -2442,8 +2604,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
return true;
}else{
s.send = false;
// Restore focus to the full form
Environment->setFocus(this);
return true;
}
}
......@@ -2488,8 +2648,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
s.send = true;
acceptInput();
s.send=false;
// Restore focus to the full form
Environment->setFocus(this);
}
}
return true;
......
......@@ -212,6 +212,7 @@ class GUIFormSpecMenu : public GUIModalMenu
}
void removeChildren();
void setInitialFocus();
/*
Remove and re-add (or reposition) stuff
*/
......@@ -225,6 +226,7 @@ class GUIFormSpecMenu : public GUIModalMenu
ItemStack verifySelectedItem();
void acceptInput();
bool preprocessEvent(const SEvent& event);
bool OnEvent(const SEvent& event);
int getListboxIndex(std::string listboxname);
......@@ -288,6 +290,7 @@ class GUIFormSpecMenu : public GUIModalMenu
v2s32 basepos;
int bp_set;
v2u32 screensize;
std::wstring focused_fieldname;
std::map<std::wstring,int> listbox_selections;
std::map<std::wstring,int> listbox_scroll;
} parserData;
......
......@@ -244,7 +244,7 @@ class MyEventReceiver : public IEventReceiver
*/
if(noMenuActive() == false)
{
return false;
return g_menumgr.preprocessEvent(event);
}
// Remember whether each key is down or up
......
......@@ -77,6 +77,15 @@ class MainMenuManager : public IMenuManager
m_stack.back()->setVisible(true);
}
// Returns true to prevent further processing
virtual bool preprocessEvent(const SEvent& event)
{
if(m_stack.size() != 0)
return m_stack.back()->preprocessEvent(event);
else
return false;
}
u32 menuCount()
{
return m_stack.size();
......
......@@ -122,6 +122,7 @@ class GUIModalMenu : public gui::IGUIElement
virtual void regenerateGui(v2u32 screensize) = 0;
virtual void drawMenu() = 0;
virtual bool preprocessEvent(const SEvent& event) { return false; };
virtual bool OnEvent(const SEvent& event) { return false; };
protected:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment