Add a screen keyboard that can be used on touch screens

This commit is contained in:
deve 2017-01-23 07:14:09 +01:00
parent d935f0318c
commit 8c8d2ac8c4
11 changed files with 606 additions and 43 deletions

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -420,13 +420,18 @@ namespace UserConfigParams
&m_multitouch_group,
"A parameter in range [0, 0.5] that determines the zone that is "
"considered as max value in steering button."));
PARAM_PREFIX FloatUserConfigParam m_multitouch_scale
PARAM_DEFAULT( FloatUserConfigParam(1.0f, "multitouch_scale",
&m_multitouch_group,
"A parameter in range [0.5, 1.5] that determines the scale of the "
"multitouch interface."));
PARAM_PREFIX BoolUserConfigParam m_screen_keyboard
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
&m_multitouch_group,
"Enable screen keyboard.") );
// ---- GP start order
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
@ -491,7 +496,7 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_texture_compression
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
&m_video_group, "Enable Texture Compression"));
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
* Bit 1: setting done by default(0), or by user choice (2). This allows
* to e.g. disable h.d. textures on hd3000 as default, but still allow the
* user to enable it. */
@ -592,7 +597,7 @@ namespace UserConfigParams
PARAM_PREFIX bool m_no_start_screen PARAM_DEFAULT( false );
PARAM_PREFIX bool m_race_now PARAM_DEFAULT( false );
PARAM_PREFIX bool m_enforce_current_player PARAM_DEFAULT( false );
/** True to test funky ambient/diffuse/specularity in RGB &
@ -910,7 +915,7 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_artist_debug_mode
PARAM_DEFAULT( BoolUserConfigParam(false, "artist_debug_mode",
"Whether to enable track debugging features") );
PARAM_PREFIX BoolUserConfigParam m_everything_unlocked
PARAM_DEFAULT( BoolUserConfigParam(false, "everything_unlocked",
"Enable all karts and tracks") );

View File

@ -673,6 +673,7 @@ namespace GUIEngine
#include "guiengine/message_queue.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "guiengine/skin.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/dialog_queue.hpp"
@ -967,6 +968,7 @@ namespace GUIEngine
g_current_screen = NULL;
needsUpdate.clearWithoutDeleting();
if (ScreenKeyboard::isActive()) ScreenKeyboard::dismiss();
if (ModalDialog::isADialogActive()) ModalDialog::dismiss();
//delete g_font;
@ -1345,12 +1347,19 @@ namespace GUIEngine
Widget* getWidget(const char* name)
{
if (ScreenKeyboard::isActive())
{
Widget* widget = ScreenKeyboard::getCurrent()->getWidget(name);
if (widget != NULL)
return widget;
}
// if a modal dialog is shown, search within it too
if (ModalDialog::isADialogActive())
{
Widget* widgetWithinDialog =
ModalDialog::getCurrent()->getWidget(name);
if (widgetWithinDialog != NULL) return widgetWithinDialog;
Widget* widget = ModalDialog::getCurrent()->getWidget(name);
if (widget != NULL)
return widget;
}
Screen* screen = getCurrentScreen();
@ -1363,12 +1372,19 @@ namespace GUIEngine
// -----------------------------------------------------------------------
Widget* getWidget(const int id)
{
if (ScreenKeyboard::isActive())
{
Widget* widget = ScreenKeyboard::getCurrent()->getWidget(id);
if (widget != NULL)
return widget;
}
// if a modal dialog is shown, search within it too
if (ModalDialog::isADialogActive())
{
Widget* widgetWithinDialog =
ModalDialog::getCurrent()->getWidget(id);
if (widgetWithinDialog != NULL) return widgetWithinDialog;
Widget* widget = ModalDialog::getCurrent()->getWidget(id);
if (widget != NULL)
return widget;
}
Screen* screen = getCurrentScreen();

View File

@ -26,6 +26,7 @@
#include "guiengine/engine.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
@ -478,9 +479,15 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo
}
// don't allow navigating to any widget when a dialog is shown; only navigate to widgets in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyIrrChild(el))
if (ScreenKeyboard::isActive())
{
el = NULL;
if (!ScreenKeyboard::getCurrent()->isMyIrrChild(el))
el = NULL;
}
else if (ModalDialog::isADialogActive())
{
if (!ModalDialog::getCurrent()->isMyIrrChild(el))
el = NULL;
}
bool found = false;
@ -501,8 +508,16 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo
if (playerID != PLAYER_ID_GAME_MASTER && !closestWidget->m_supports_multiplayer) return;
// if a dialog is shown, restrict to items in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(closestWidget))
continue;
if (ScreenKeyboard::isActive())
{
if (!ScreenKeyboard::getCurrent()->isMyChild(closestWidget))
continue;
}
else if (ModalDialog::isADialogActive())
{
if (!ModalDialog::getCurrent()->isMyChild(closestWidget))
continue;
}
if (NAVIGATION_DEBUG)
{
@ -537,7 +552,12 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo
// select the last/first widget
Widget* wrapWidget = NULL;
if (ModalDialog::isADialogActive())
if (ScreenKeyboard::isActive())
{
wrapWidget = reverse ? ScreenKeyboard::getCurrent()->getLastWidget():
ScreenKeyboard::getCurrent()->getFirstWidget();
}
else if (ModalDialog::isADialogActive())
{
wrapWidget = reverse ? ModalDialog::getCurrent()->getLastWidget() :
ModalDialog::getCurrent()->getFirstWidget();
@ -558,6 +578,14 @@ void EventHandler::navigate(const int playerID, Input::InputType type, const boo
void EventHandler::sendEventToUser(GUIEngine::Widget* widget, std::string& name, const int playerID)
{
if (ScreenKeyboard::isActive())
{
if (ScreenKeyboard::getCurrent()->processEvent(widget->m_properties[PROP_ID]) == EVENT_BLOCK)
{
return;
}
}
if (ModalDialog::isADialogActive())
{
if (ModalDialog::getCurrent()->processEvent(widget->m_properties[PROP_ID]) == EVENT_BLOCK)
@ -579,6 +607,14 @@ EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int
Widget* parent = w->m_event_handler;
if (ScreenKeyboard::isActive())
{
if (ScreenKeyboard::getCurrent()->processEvent(w->m_properties[PROP_ID]) == EVENT_BLOCK)
{
return EVENT_BLOCK;
}
}
if (ModalDialog::isADialogActive() && (parent == NULL || parent->m_type != GUIEngine::WTYPE_RIBBON))
{
if (ModalDialog::getCurrent()->processEvent(w->m_properties[PROP_ID]) == EVENT_BLOCK)
@ -670,10 +706,23 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
if (!w->isFocusable() || !w->isActivated()) return GUIEngine::EVENT_BLOCK;
// When a modal dialog is shown, don't select widgets out of the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(w))
if (ScreenKeyboard::isActive())
{
// check for parents too before discarding event
if (w->m_event_handler != NULL)
if (!ScreenKeyboard::getCurrent()->isMyChild(w) &&
w->m_event_handler != NULL)
{
if (!ScreenKeyboard::getCurrent()->isMyChild(w->m_event_handler))
{
break;
}
}
}
else if (ModalDialog::isADialogActive())
{
// check for parents too before discarding event
if (!ModalDialog::getCurrent()->isMyChild(w) &&
w->m_event_handler != NULL)
{
if (!ModalDialog::getCurrent()->isMyChild(w->m_event_handler))
{
@ -771,7 +820,8 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
{
// currently, enter pressed in text ctrl events can only happen in dialogs.
// FIXME : find a cleaner way to route the event to its proper location
if (ModalDialog::isADialogActive()) ModalDialog::onEnterPressed();
if (!ScreenKeyboard::isActive() && ModalDialog::isADialogActive())
ModalDialog::onEnterPressed();
break;
}
default:

View File

@ -0,0 +1,319 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License: or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "guiengine/layout_manager.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/CGUIEditBox.hpp"
#include "utils/log.hpp"
#include <string>
using namespace GUIEngine;
#define KEYBOARD_COLS_NUM 11
#define KEYBOARD_ROWS_NUM 3
typedef std::string KeyboardLayout[KEYBOARD_ROWS_NUM][KEYBOARD_COLS_NUM];
KeyboardLayout layout_lower =
{{"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "123" },
{"a", "s", "d", "f", "g", "h", "j", "k", "l", "Back", "Shift"},
{"z", "x", "c", "v", "b", "n", "m", ",", ".", "Space", "Enter"}};
KeyboardLayout layout_upper =
{{"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "123" },
{"A", "S", "D", "F", "G", "H", "J", "K", "L", "Back", "Shift"},
{"Z", "X", "C", "V", "B", "N", "M", ",", ".", "Space", "Enter"}};
KeyboardLayout layout_digits =
{{"1", "2", "3", "!", "@", "#", "$", "%", "^", "&", "Text" },
{"4", "5", "6", "*", "(", ")", "-", "_", "=", "Back", "Shift"},
{"7", "8", "9", "0", "+", "/", "?", ",", ".", "Space", "Enter"}};
KeyboardLayout layout_digits2 =
{{"1", "2", "3", "[", "]", "{", "}", ";", ":", "\\", "Text" },
{"4", "5", "6", "|", "\'", "\"", "<", ">", "`", "Back", "Shift"},
{"7", "8", "9", "0", "~", "/", "?", ",", ".", "Space", "Enter"}};
ScreenKeyboard* ScreenKeyboard::m_screen_keyboard = NULL;
// ----------------------------------------------------------------------------
/** The screen keyboard constructor
* \param percent_width A relative value in range of 0.0 to 1.0 that
* determines width of the screen that will be used by the keyboard.
* \param percent_height A relative value in range of 0.0 to 1.0 that
* determines height of the screen that will be used by the keyboard.
* \param edit_box The edit box that is assigned to the keyboard.
*/
ScreenKeyboard::ScreenKeyboard(float percent_width, float percent_height,
CGUIEditBox* edit_box)
{
if (m_screen_keyboard != NULL)
{
delete m_screen_keyboard;
Log::warn("GUIEngine", "Showing a screen keyboard while the previous "
"one is still open. Destroying the previous keyboard.");
}
m_screen_keyboard = this;
m_buttons_type = BUTTONS_NONE;
m_percent_width = std::min(std::max(percent_width, 0.0f), 1.0f);
m_percent_height = std::min(std::max(percent_height, 0.0f), 1.0f);
m_irrlicht_window = NULL;
m_edit_box = edit_box;
init();
} // ScreenKeyboard
// ----------------------------------------------------------------------------
/** The screen keyboard destructor
*/
ScreenKeyboard::~ScreenKeyboard()
{
m_screen_keyboard = NULL;
GUIEngine::getGUIEnv()->removeFocus(m_irrlicht_window);
m_irrlicht_window->remove();
input_manager->setMode(m_previous_mode);
elementsWereDeleted();
} // ~ScreenKeyboard
// ----------------------------------------------------------------------------
/** Internal function that makes whole screen keyboard initialization
*/
void ScreenKeyboard::init()
{
const core::dimension2d<u32>& frame_size = irr_driver->getFrameSize();
int margin = 15;
int w = frame_size.Width * m_percent_width;
int h = frame_size.Height * m_percent_height;
int x = frame_size.Width/2 - w/2;
int y = frame_size.Height - h - margin;
if (m_edit_box != NULL)
{
core::rect<s32> pos = m_edit_box->getAbsolutePosition();
if (pos.LowerRightCorner.Y + 5 > y)
{
y = margin;
}
}
m_area = core::rect<s32>(x, y, x + w, y + h);
m_irrlicht_window = GUIEngine::getGUIEnv()->addWindow(m_area, true);
m_irrlicht_window->setDrawTitlebar(false);
m_irrlicht_window->getCloseButton()->setVisible(false);
m_irrlicht_window->setDraggable(UserConfigParams::m_artist_debug_mode);
m_previous_mode=input_manager->getMode();
input_manager->setMode(InputManager::MENU);
createButtons();
assignButtons(BUTTONS_LOWER);
} // init
// ----------------------------------------------------------------------------
/** Creates all button widgets
*/
void ScreenKeyboard::createButtons()
{
int pos_x = 1;
int pos_y = 10;
int width = (m_area.getWidth() - 2 * pos_x) / KEYBOARD_COLS_NUM;
int height = (m_area.getHeight() - 2 * pos_y) / KEYBOARD_ROWS_NUM;
char width_str[100];
sprintf(width_str, "%i", width);
char height_str[100];
sprintf(height_str, "%i", height);
for (int i = 0; i < KEYBOARD_ROWS_NUM; i++)
{
char tmp[100];
sprintf(tmp, "%i", pos_y + height * i);
std::string pos_y_str = tmp;
for (int j = 0; j < KEYBOARD_COLS_NUM; j++)
{
char tmp[100];
sprintf(tmp, "%i", pos_x + width * j);
std::string pos_x_str = tmp;
ButtonWidget* button = new ButtonWidget();
button->setParent(m_irrlicht_window);
button->m_properties[PROP_WIDTH] = width_str;
button->m_properties[PROP_HEIGHT] = height_str;
button->m_properties[PROP_X] = pos_x_str;
button->m_properties[PROP_Y] = pos_y_str;
m_widgets.push_back(button);
m_buttons.push_back(button);
}
}
LayoutManager::calculateLayout(m_widgets, this);
addWidgetsRecursively(m_widgets);
} // createButtons
// ----------------------------------------------------------------------------
/** A function that allows to select one of the available buttons layout
* \param buttons_type One of the available buttons type
*/
void ScreenKeyboard::assignButtons(ButtonsType buttons_type)
{
m_buttons_type = buttons_type;
KeyboardLayout* keys = NULL;
switch (buttons_type)
{
case BUTTONS_LOWER:
keys = &layout_lower;
break;
case BUTTONS_UPPER:
keys = &layout_upper;
break;
case BUTTONS_DIGITS:
keys = &layout_digits;
break;
case BUTTONS_DIGITS2:
keys = &layout_digits2;
break;
default:
keys = NULL;
break;
};
for (int i = 0; i < KEYBOARD_ROWS_NUM; i++)
{
for (int j = 0; j < KEYBOARD_COLS_NUM; j++)
{
std::string key = keys != NULL ? (*keys)[i][j] : "?";
ButtonWidget* button = m_buttons[i * KEYBOARD_COLS_NUM + j];
button->setText(key.c_str());
button->m_properties[PROP_ID] = key;
}
}
} // assignButtons
// ----------------------------------------------------------------------------
/** A function that handles buttons events
* \param eventSource Button ID
* \return Block event if edit box is assigned
*/
EventPropagation ScreenKeyboard::processEvent(const std::string& eventSource)
{
if (m_edit_box == NULL)
return EVENT_LET;
SEvent event;
bool send_event = false;
if (eventSource == "Shift")
{
switch (m_buttons_type)
{
case BUTTONS_UPPER:
assignButtons(BUTTONS_LOWER);
break;
case BUTTONS_LOWER:
assignButtons(BUTTONS_UPPER);
break;
case BUTTONS_DIGITS:
assignButtons(BUTTONS_DIGITS2);
break;
case BUTTONS_DIGITS2:
assignButtons(BUTTONS_DIGITS);
break;
default:
break;
}
}
else if (eventSource == "123")
{
assignButtons(BUTTONS_DIGITS);
}
else if (eventSource == "Text")
{
assignButtons(BUTTONS_LOWER);
}
else if (eventSource == "Enter")
{
dismiss();
return EVENT_BLOCK;
}
else if (eventSource == "Back")
{
event.KeyInput.Key = KEY_BACK;
event.KeyInput.Char = 0;
send_event = true;
}
else if (eventSource == "Space")
{
event.KeyInput.Key = KEY_UNKNOWN;
event.KeyInput.Char = ' ';
send_event = true;
}
else if (eventSource.size() > 0)
{
event.KeyInput.Key = KEY_UNKNOWN;
event.KeyInput.Char = eventSource.at(0);
send_event = true;
}
if (send_event)
{
event.EventType = EET_KEY_INPUT_EVENT;
event.KeyInput.PressedDown = true;
event.KeyInput.Control = false;
event.KeyInput.Shift = false;
m_edit_box->OnEvent(event);
}
return EVENT_BLOCK;
} // processEvent
// ----------------------------------------------------------------------------
/** A function that closes the keyboard
*/
void ScreenKeyboard::dismiss()
{
delete m_screen_keyboard;
m_screen_keyboard = NULL;
} // dismiss
// ----------------------------------------------------------------------------
/** A function that handles escape pressed event
*/
bool ScreenKeyboard::onEscapePressed()
{
dismiss();
return true;
} // onEscapePressed
// ----------------------------------------------------------------------------

View File

@ -0,0 +1,129 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License: or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SCREEN_KEYBOARD_HPP
#define HEADER_SCREEN_KEYBOARD_HPP
#include <IGUIWindow.h>
#include "guiengine/abstract_top_level_container.hpp"
#include "guiengine/skin.hpp"
#include "input/input_manager.hpp"
#include "utils/leak_check.hpp"
class CGUIEditBox;
/**
* \ingroup guiengine
*/
namespace GUIEngine
{
class ButtonWidget;
/**
* \brief Class representing a screen keyboard. Only once instance at a
* time (if you create a 2nd the first will be destroyed). You can call
* static function 'dismiss' to simply close the keyboard (so you don't
* need to keep track of instances yourself)
* \ingroup guiengine
*/
class ScreenKeyboard : public SkinWidgetContainer,
public AbstractTopLevelContainer
{
private:
enum ButtonsType
{
BUTTONS_NONE,
BUTTONS_LOWER,
BUTTONS_UPPER,
BUTTONS_DIGITS,
BUTTONS_DIGITS2
};
/** Global instance of the current screen keyboard */
static ScreenKeyboard* m_screen_keyboard;
/** A value in range of 0.0 to 1.0 that determines width of the screen
* that is used by the keyboard */
float m_percent_width;
/** A value in range of 0.0 to 1.0 that determines height of the screen
* that is used by the keyboard */
float m_percent_height;
/** The edit box that is assigned to the keyboard */
CGUIEditBox* m_edit_box;
/** Remembers currently selected button type */
ButtonsType m_buttons_type;
/** Irrlicht window used by the keyboard widget */
irr::gui::IGUIWindow* m_irrlicht_window;
/** Contains position and dimensions of the keyboard */
irr::core::rect<irr::s32> m_area;
/** Contans the pointers to all button widgets */
std::vector<ButtonWidget*> m_buttons;
/** Remembered input mode that was used before keyboard creation */
InputManager::InputDriverMode m_previous_mode;
void init();
void createButtons();
void assignButtons(ButtonsType buttons_type);
public:
LEAK_CHECK()
ScreenKeyboard(float percent_width, float percent_height,
CGUIEditBox* edit_box);
~ScreenKeyboard();
virtual EventPropagation processEvent(const std::string& eventSource);
static void dismiss();
static bool onEscapePressed();
/** Returns pointer to the created keyboard or NULL if keyboard was
* not created */
static ScreenKeyboard* getCurrent() {return m_screen_keyboard;}
/** Returns true if keyboard is created */
static bool isActive() {return m_screen_keyboard != NULL;}
/** Get irrlicht window used by the keyboard widget */
irr::gui::IGUIWindow* getIrrlichtElement() {return m_irrlicht_window;}
/** Checks if the screen keyboard is a parent of the selected item
* \param widget A widget that should be checked
* \return True if keyboard is the parent
*/
bool isMyIrrChild(irr::gui::IGUIElement* widget) const
{return m_irrlicht_window->isMyChild(widget);}
/** Returns width of the screen keyboard */
int getWidth() {return m_area.getWidth();}
/** Returns height of the screen keyboard */
int getHeight() {return m_area.getHeight();}
};
}
#endif

View File

@ -29,6 +29,7 @@
#include "guiengine/modaldialog.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "guiengine/widgets.hpp"
#include "io/file_manager.hpp"
#include "states_screens/state_manager.hpp"
@ -2299,32 +2300,41 @@ core::recti Skin::draw3DWindowBackground(IGUIElement *element,
const core::recti *clip,
core::recti* checkClientArea)
{
if (ModalDialog::getCurrent() == NULL) return rect;
if (ModalDialog::getCurrent()->fadeBackground())
drawBGFadeColor();
// draw frame
if (m_dialog_size < 1.0f)
if (ScreenKeyboard::getCurrent() &&
ScreenKeyboard::getCurrent()->getIrrlichtElement() == element)
{
core::recti sized_rect = rect;
core::position2d<s32> center = sized_rect.getCenter();
const int w = sized_rect.getWidth();
const int h = sized_rect.getHeight();
const float texture_size = sin(m_dialog_size*M_PI*0.5f);
sized_rect.UpperLeftCorner.X = (int)(center.X -(w/2.0f)*texture_size);
sized_rect.UpperLeftCorner.Y = (int)(center.Y -(h/2.0f)*texture_size);
sized_rect.LowerRightCorner.X = (int)(center.X +(w/2.0f)*texture_size);
sized_rect.LowerRightCorner.Y = (int)(center.Y +(h/2.0f)*texture_size);
drawBoxFromStretchableTexture( ModalDialog::getCurrent(), sized_rect,
SkinConfig::m_render_params["window::neutral"]);
m_dialog_size += GUIEngine::getLatestDt()*5;
drawBoxFromStretchableTexture( ScreenKeyboard::getCurrent(), rect,
SkinConfig::m_render_params["window::neutral"]);
}
else
else if (ModalDialog::getCurrent() &&
ModalDialog::getCurrent()->getIrrlichtElement() == element)
{
drawBoxFromStretchableTexture( ModalDialog::getCurrent(), rect,
if (ModalDialog::getCurrent()->fadeBackground())
drawBGFadeColor();
// draw frame
if (m_dialog_size < 1.0f)
{
core::recti sized_rect = rect;
core::position2d<s32> center = sized_rect.getCenter();
const int w = sized_rect.getWidth();
const int h = sized_rect.getHeight();
const float tex_size = sin(m_dialog_size*M_PI*0.5f);
sized_rect.UpperLeftCorner.X = (int)(center.X -(w/2.0f)*tex_size);
sized_rect.UpperLeftCorner.Y = (int)(center.Y -(h/2.0f)*tex_size);
sized_rect.LowerRightCorner.X = (int)(center.X +(w/2.0f)*tex_size);
sized_rect.LowerRightCorner.Y = (int)(center.Y +(h/2.0f)*tex_size);
drawBoxFromStretchableTexture(ModalDialog::getCurrent(), sized_rect,
SkinConfig::m_render_params["window::neutral"]);
m_dialog_size += GUIEngine::getLatestDt()*5;
}
else
{
drawBoxFromStretchableTexture(ModalDialog::getCurrent(), rect,
SkinConfig::m_render_params["window::neutral"]);
}
}
return rect;

View File

@ -12,8 +12,10 @@
//#include "os.h"
#include "Keycodes.h"
#include "config/user_config.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "utils/time.hpp"
@ -1236,6 +1238,7 @@ bool CGUIEditBox::processMouse(const SEvent& event)
#endif
setTextMarkers(CursorPos, CursorPos );
calculateScrollPos();
return true;
}
else if (!m_rtl)
@ -1245,6 +1248,19 @@ bool CGUIEditBox::processMouse(const SEvent& event)
{
return false;
}
else if (UserConfigParams::m_screen_keyboard)
{
CursorPos = Text.size();
setTextMarkers(CursorPos, CursorPos);
calculateScrollPos();
if (GUIEngine::ScreenKeyboard::getCurrent() == NULL)
{
new GUIEngine::ScreenKeyboard(0.98, 0.30, this);
}
return true;
}
else
{
// move cursor
@ -1264,6 +1280,7 @@ bool CGUIEditBox::processMouse(const SEvent& event)
MouseMarking = true;
setTextMarkers( newMarkBegin, CursorPos);
calculateScrollPos();
return true;
}
}

View File

@ -25,6 +25,7 @@
#include "guiengine/event_handler.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "input/device_manager.hpp"
#include "input/gamepad_device.hpp"
#include "input/keyboard_device.hpp"
@ -663,9 +664,13 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
}
}
if (button == KEY_RETURN && GUIEngine::ModalDialog::isADialogActive())
if (button == KEY_RETURN)
{
GUIEngine::ModalDialog::onEnterPressed();
if (GUIEngine::ModalDialog::isADialogActive() &&
!GUIEngine::ScreenKeyboard::isActive())
{
GUIEngine::ModalDialog::onEnterPressed();
}
}
if (action != PA_BEFORE_FIRST)
@ -732,6 +737,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
// ... when in-game
if (StateManager::get()->getGameState() == GUIEngine::GAME &&
!GUIEngine::ModalDialog::isADialogActive() &&
!GUIEngine::ScreenKeyboard::isActive() &&
!race_manager->isWatchingReplay() )
{
if (player == NULL)
@ -1171,6 +1177,7 @@ EventPropagation InputManager::input(const SEvent& event)
if (getDeviceManager()->getAssignMode() != NO_ASSIGN &&
!GUIEngine::isWithinATextBox() &&
(!GUIEngine::ModalDialog::isADialogActive() &&
!GUIEngine::ScreenKeyboard::isActive() &&
StateManager::get()->getGameState() == GUIEngine::GAME))
{
return EVENT_BLOCK;

View File

@ -25,6 +25,7 @@
#include "karts/controller/controller.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen_keyboard.hpp"
// ----------------------------------------------------------------------------
/** The multitouch device constructor
@ -263,6 +264,7 @@ void MultitouchDevice::handleControls(MultitouchButton* button)
// to use it for GUI navigation.
if (StateManager::get()->getGameState() != GUIEngine::GAME ||
GUIEngine::ModalDialog::isADialogActive() ||
GUIEngine::ScreenKeyboard::isActive() ||
race_manager->isWatchingReplay())
return;

View File

@ -25,6 +25,7 @@
#include "guiengine/engine.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "input/input_device.hpp"
#include "input/input_manager.hpp"
#include "main_loop.hpp"
@ -163,10 +164,17 @@ void StateManager::escapePressed()
if(input_manager->isInMode(InputManager::INPUT_SENSE_KEYBOARD) ||
input_manager->isInMode(InputManager::INPUT_SENSE_GAMEPAD) )
{
ScreenKeyboard::dismiss();
ModalDialog::dismiss();
input_manager->setMode(InputManager::MENU);
}
// when another modal dialog is visible
else if(ScreenKeyboard::isActive())
{
if(ScreenKeyboard::getCurrent()->onEscapePressed())
ScreenKeyboard::getCurrent()->dismiss();
}
// when another modal dialog is visible
else if(ModalDialog::isADialogActive())
{
if(ModalDialog::getCurrent()->onEscapePressed())