Add a screen keyboard that can be used on touch screens
This commit is contained in:
parent
d935f0318c
commit
8c8d2ac8c4
@ -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/*")
|
||||
|
@ -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") );
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
319
src/guiengine/screen_keyboard.cpp
Normal file
319
src/guiengine/screen_keyboard.cpp
Normal 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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
129
src/guiengine/screen_keyboard.hpp
Normal file
129
src/guiengine/screen_keyboard.hpp
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user