Files
GTASource/game/frontend/TextInputBox.cpp

903 lines
81 KiB
C++
Raw Permalink Normal View History

2025-02-23 17:40:52 +08:00
#if RSG_PC
#include "TextInputBox.h"
#include "Frontend/ui_channel.h"
#include "Frontend/PauseMenu.h"
#include "system/keyboard.h"
#include "Frontend/NewHud.h"
#if __BANK
#include "bank/bkmgr.h"
#include "game/localisation.h"
#include "input/virtualkeyboard.h"
#endif // __BANK
//OPTIMISATIONS_OFF();
#define TEXT_INPUT_BOX_MOVIE_NAME "TEXT_INPUT_BOX"
#define MOVIE_CONTENT_MC "CONTENT"
#define MOVIE_INPUT_TEXTFIELD "InputTF"
#define KEY_HELD_THRESHOLD 100
#if __BANK
#define UTF_16_SPEW 1
#define DEBUG_STRING_SIZE ioVirtualKeyboard::MAX_STRING_LENGTH_FOR_VIRTUAL_KEYBOARD
char s_pszDebugTitle[DEBUG_STRING_SIZE];
char s_pszDebugDescription[DEBUG_STRING_SIZE];
char s_pszDebugDefaultInput[DEBUG_STRING_SIZE];
char16 s_pszDebugTitle16[DEBUG_STRING_SIZE];
char16 s_pszDebugDescription16[DEBUG_STRING_SIZE];
char16 s_pszDebugDefaultInput16[DEBUG_STRING_SIZE];
int s_iInputBoxState;
#endif //__BANK
atArray<CMenuButtonWithSound> CTextInputBox::ms_ButtonData;
atRangeArray<u64,4> CTextInputBox::ms_AffectedButtonMasks;
CScaleformMovieWrapper CTextInputBox::ms_Movie;
CTextInputBox::CTextInputBox() :
m_bEnabled(true)
, m_bActive(false)
, m_bImeTextInputHasFocus(false)
, m_bWaitForEnterRelease(false)
, m_bWaitForBackRelease(false)
, m_bCursorThisFrame(false)
, m_bCursorPreviousFrame(false)
, m_bAllowComma(false)
, m_uLastInputTime(0)
, m_uCursorLocation(0)
, m_uMaxLength(0)
, m_uKeyHeldDelay(0)
{
m_eState = ioVirtualKeyboard::kKBState_INVALID;
memset(m_Text, '\0', sizeof(m_Text));
m_AcceptCallback = NullCallback;
m_DeclineCallback = NullCallback;
}
void CTextInputBox::Init(unsigned initMode)
{
if( initMode == INIT_CORE )
{
if (!STextInputBox::IsInstantiated())
{
STextInputBox::Instantiate();
}
REGISTER_FRONTEND_XML(CTextInputBox::HandleXML, "TextEntryBox");
// preload some entries so we can live happily due to startup procedures needing this nearly instantly
if( ms_ButtonData.empty() )
{
ms_ButtonData.ResizeGrow(2);
int iBitIndex = 1;
CMenuButtonWithSound& OKButton = ms_ButtonData[iBitIndex];
OKButton.m_ButtonInput = INPUT_FRONTEND_ACCEPT;
OKButton.m_ButtonInputGroup = INPUTGROUP_INVALID;
OKButton.m_RawButtonIcon = ICON_INVALID;
OKButton.m_hButtonHash.SetFromString("IB_OK");
int iButton = GetButtonMaskIndex(OKButton.m_ButtonInput);
if( iButton != -1 )
{
ms_AffectedButtonMasks[iButton] |= BIT_64(iBitIndex);
}
}
}
}
void CTextInputBox::Shutdown(unsigned shutdownMode)
{
if ( shutdownMode == rage::SHUTDOWN_CORE )
{
if (STextInputBox::IsInstantiated())
{
STextInputBox::Destroy();
}
}
}
void CTextInputBox::Open(const ioVirtualKeyboard::Params& WIN32PC_ONLY(params))
{
if(!m_bEnabled)
{
return;
}
#if !__FINAL
if(CControlMgr::GetKeyboard().GetKeyboardMode() != KEYBOARD_MODE_GAME)
{
CControlMgr::GetKeyboard().SetCurrentMode(KEYBOARD_MODE_GAME);
}
#endif // !__FINAL
if(!m_bActive)
{
LoadTextInputBoxMovie();
}
//UpdateDisplayParam();
m_bCursorThisFrame = false;
m_bCursorPreviousFrame = false;
m_uLastInputTime = 0;
m_uCursorLocation = 0;
m_uKeyHeldDelay = 0;
m_uMaxLength = params.m_MaxLength;
memset(m_Text, '\0', sizeof(m_Text));
m_eTextType = params.m_KeyboardType;
SetValidCharacters();
SetInvalidCharacters();
ioKeyboard::SetKeyboardLayoutSwitchingEnable(true);
if(CScaleformMgr::BeginMethod(m_iMovieID, SF_BASE_CLASS_GENERIC, "SET_MULTI_LINE"))
{
bool bUseMultiLine = false;
switch (params.m_MultiLineUsage)
{
case ioVirtualKeyboard::Params::FORCE_SINGLE_LINE :
bUseMultiLine = false;
break;
case ioVirtualKeyboard::Params::FORCE_MULTI_LINE :
bUseMultiLine = true;
break;
case ioVirtualKeyboard::Params::USE_MULTI_LINE_FOR_LONG_STRINGS :
{
const int MAX_SINGLE_LINE_SIZE = 32;
bUseMultiLine = m_uMaxLength > MAX_SINGLE_LINE_SIZE;
}
break;
}
CScaleformMgr::AddParamBool(bUseMultiLine); // DEFAULT VALUE
CScaleformMgr::EndMethod();
}
if(CScaleformMgr::BeginMethod(m_iMovieID, SF_BASE_CLASS_GENERIC, "SET_TEXT_BOX"))
{
const int MAX_STR_LENGTH = ioVirtualKeyboard::MAX_STRING_LENGTH_FOR_VIRTUAL_KEYBOARD;
char title[MAX_STR_LENGTH] = { 0 };
char description[MAX_STR_LENGTH] = { 0 };
if( params.m_Title != NULL )
{
WideToUtf8( title, params.m_Title, MAX_STR_LENGTH );
}
if( params.m_Description != NULL )
{
WideToUtf8( description, params.m_Description, MAX_STR_LENGTH );
}
if(params.m_InitialValue != NULL)
{
safecpy( m_Text, params.m_InitialValue, NELEM(m_Text) );
}
m_uCursorLocation = (u32)StringLengthChar16(m_Text);
// note: currently title doesn't do anything so it has to be swapped with description.
USES_CONVERSION;
CScaleformMgr::AddParamString(description); // TITLE
CScaleformMgr::AddParamString(title); // DESCRIPTION
CScaleformMgr::AddParamString(WIDE_TO_UTF8(m_Text), false); // DEFAULT VALUE
CScaleformMgr::EndMethod();
if(ms_Movie.BeginMethod("SET_CURSOR_LOCATION"))
{
ms_Movie.AddParam(m_uCursorLocation);
ms_Movie.EndMethod();
}
m_eState = ioVirtualKeyboard::kKBState_PENDING;
ioValue::ReadOptions options;
options.SetFlags(ioValue::ReadOptions::F_READ_DISABLED, true);
const CControl& control = CControlMgr::GetMainFrontendControl();
m_bWaitForEnterRelease = control.GetFrontendAccept().IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options) ||
control.GetFrontendAccept().IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options);
#if RSG_PC
const bool isKBM = control.WasKeyboardMouseLastKnownSource();
const ioValue& enterExit = control.GetFrontendEnterExitAlternate();
const ioValue& back = control.GetFrontendCancel();
m_bWaitForBackRelease = (isKBM && (enterExit.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options) || enterExit.IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options)) ) ||
(isKBM == false && (back.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options) || back.IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options)) );
#else
m_bWaitForBackRelease = false;
#endif
CTextInputBox::SetInstructionalButtons(CControlMgr::GetPlayerMappingControl().WasKeyboardMouseLastKnownSource() ? FE_WARNING_OK | FE_WARNING_QUIT : FE_WARNING_OK_CANCEL);
m_bLastInputKeyboard = CControlMgr::GetPlayerMappingControl().WasKeyboardMouseLastKnownSource();
return;
}
m_eState = ioVirtualKeyboard::kKBState_FAILED;
}
//////////////////////////////////////////////////////////////////////////
void CTextInputBox::HandleXML( parTreeNode* pButtonMenu )
{
parTreeNode::ChildNodeIterator pChildrenStart = pButtonMenu->BeginChildren();
parTreeNode::ChildNodeIterator pChildrenEnd = pButtonMenu->EndChildren();
// first, we have to find the highest bitindex in the list (we can't use NumChildren because bits may go dead)
int iHighestBitIndex = -1;
for(parTreeNode::ChildNodeIterator ci = pChildrenStart; ci != pChildrenEnd; ++ci)
{
parElement& rCurElement = (*ci)->GetElement();
iHighestBitIndex = Max(rCurElement.FindAttributeIntValue("BitIndex", -1, true), iHighestBitIndex);
}
ms_ButtonData.Reset();
ms_ButtonData.ResizeGrow(iHighestBitIndex+1); // +1 to adjust for Zero
for(parTreeNode::ChildNodeIterator ci = pChildrenStart; ci != pChildrenEnd; ++ci)
{
parElement& rCurElement = (*ci)->GetElement();
// check for bitIndex
u32 iBitIndex = rCurElement.FindAttributeIntValue("BitIndex", -1, true);
if( iBitIndex == -1 || !uiVerifyf(iBitIndex >= 0 && iBitIndex < 64, "Can only handle 64-bit values for bitindex! '%u' is just out of range!", iBitIndex) )
continue;
CMenuButtonWithSound& curSound = ms_ButtonData[iBitIndex];
PARSER.LoadObject(*ci, curSound);
uiAssertf(curSound.m_ButtonInput != UNDEFINED_INPUT || curSound.m_ButtonInputGroup != INPUTGROUP_INVALID || curSound.m_RawButtonIcon != ICON_INVALID,
"Invalid button icon!");
// set up sound
char temp[32];
curSound.m_Sound.SetFromString( rCurElement.FindAttributeStringValue("Sound", "SELECT", temp, 32) );
int iButton = GetButtonMaskIndex(curSound.m_ButtonInput);
if( iButton != -1 )
{
ms_AffectedButtonMasks[iButton] |= BIT_64(iBitIndex);
}
}
}
void CTextInputBox::UpdateDisplayParam()
{
if(CScaleformMgr::BeginMethod(m_iMovieID, SF_BASE_CLASS_GENERIC, "UPDATE_DISPLAY_PARAMS"))
{
CScaleformMgr::AddParamInt(VideoResManager::GetUIWidth());
CScaleformMgr::AddParamInt(VideoResManager::GetUIHeight());
CScaleformMgr::EndMethod();
}
}
void CTextInputBox::SetCursorLocation(int iCursorLocation)
{
if(uiVerify(iCursorLocation >= 0 && iCursorLocation < m_uMaxLength))
{
m_uCursorLocation = (u32)iCursorLocation;
}
}
void CTextInputBox::HandleInput()
{
ioValue::ReadOptions options;
options.SetFlags(ioValue::ReadOptions::F_READ_DISABLED, true);
const CControl& control = CControlMgr::GetMainFrontendControl();
const ioValue& exit = control.GetFrontendEnterExitAlternate();
const ioValue& cancel = control.GetFrontendCancel();
const ioValue& left = control.GetFrontendLeft();
const ioValue& right = control.GetFrontendRight();
const ioValue& up = control.GetFrontendUp();
const ioValue& down = control.GetFrontendDown();
// For the arrow movement keys.
bool bCursorLocChanged = false;
bool bTextChanged = false;
if(m_bImeTextInputHasFocus)
{
const ioValue& accept = control.GetFrontendAccept();
// Clear IME input focus when both buttons are up. This will be reset next frame if it still has input focus. Note, we require two frames up so
// that IsReleased() does not cause the input window to close.
m_bImeTextInputHasFocus = ioKeyboard::ImeIsInProgress() ||
accept.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options) ||
accept.WasDown(ioValue::BUTTON_DOWN_THRESHOLD, options) ||
exit.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options) ||
exit.WasDown(ioValue::BUTTON_DOWN_THRESHOLD, options);
}
else
{
if(m_bWaitForEnterRelease || m_bWaitForBackRelease)
{
if(control.GetFrontendAccept().IsUp(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
m_bWaitForEnterRelease = false;
}
// When using keyboard/mouse use GetFrontendEnterExit (escape key), otherwise use the GetFrontendCancel (controller B/O button).
if( (cancel.GetLastSource().m_DeviceIndex != ioSource::IOMD_KEYBOARD_MOUSE && cancel.IsUp(ioValue::BUTTON_DOWN_THRESHOLD, options)) ||
(exit.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE) && exit.IsUp(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
m_bWaitForBackRelease = false;
}
return;
}
if (control.GetFrontendAccept().IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
m_eState = ioVirtualKeyboard::kKBState_SUCCESS;
m_AcceptCallback.Call();
Close();
return;
}
// When using keyboard/mouse use GetFrontendEnterExit (escape key), otherwise use the GetFrontendCancel (controller B/O button).
if( CMousePointer::IsMouseBack() ||
(cancel.GetLastSource().m_DeviceIndex != ioSource::IOMD_KEYBOARD_MOUSE && cancel.IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options)) ||
(exit.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE && exit.IsReleased(ioValue::BUTTON_DOWN_THRESHOLD, options)))
{
m_eState = ioVirtualKeyboard::kKBState_CANCELLED;
m_DeclineCallback.Call();
Close();
return;
}
// Arrow keys
GFxKey::Code keyPressed = GFxKey::Code::VoidSymbol;
if(left.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE && left.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
if (m_uCursorLocation > 0 &&
fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
m_uCursorLocation--;
bCursorLocChanged = true;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
keyPressed = GFxKey::Code::Left;
}
}
if(right.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE && right.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
if(m_uCursorLocation < m_uMaxLength)
{
if (m_Text[m_uCursorLocation + 1] != '\0' &&
fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
m_uCursorLocation++;
bCursorLocChanged = true;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
keyPressed = GFxKey::Code::Right;
}
else if(m_Text[m_uCursorLocation] != '\0' && m_Text[m_uCursorLocation + 1] == '\0' &&
fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
m_uCursorLocation++;
bCursorLocChanged = true;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
keyPressed = GFxKey::Code::Right;
}
}
}
if(up.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE && up.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
if(fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
keyPressed = GFxKey::Code::Up;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
}
}
else if(down.GetLastSource().m_DeviceIndex == ioSource::IOMD_KEYBOARD_MOUSE && down.IsDown(ioValue::BUTTON_DOWN_THRESHOLD, options))
{
if(fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
keyPressed = GFxKey::Code::Down;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
}
}
if(keyPressed != GFxKey::Code::VoidSymbol && ms_Movie.BeginMethod("HANDLE_KEY_PRESS"))
{
ms_Movie.AddParam(keyPressed);
ms_Movie.EndMethod();
}
if (CControlMgr::GetKeyboard().GetKeyDown(KEY_DELETE, KEYBOARD_MODE_GAME) &&
fwTimer::GetSystemTimeInMilliseconds() - m_uKeyHeldDelay > KEY_HELD_THRESHOLD)
{
ShiftArrayBack(m_uCursorLocation);
bTextChanged = true;
m_uKeyHeldDelay = fwTimer::GetSystemTimeInMilliseconds();
}
}
const char16 *pInputBuffer = ioKeyboard::GetInputText();
// There is no PC text and text hasn't changed (i.e. deleted)
if((pInputBuffer == NULL || pInputBuffer[0] == '\0') && !bTextChanged)
{
if(bCursorLocChanged && ms_Movie.BeginMethod("SET_CURSOR_LOCATION"))
{
ms_Movie.AddParam(m_uCursorLocation);
ms_Movie.EndMethod();
}
return;
}
for(u32 i = 0; i < ioKeyboard::TEXT_BUFFER_LENGTH && pInputBuffer[i] != '\0'; ++i)
{
// add each character.
if(pInputBuffer[i] == KEY_BACK)
{
if(m_uCursorLocation > 0)
{
ShiftArrayBack(m_uCursorLocation - 1);
m_uCursorLocation--;
}
}
if(!CTextFormat::DoesCharacterExistInFont(FONT_STYLE_STANDARD, pInputBuffer[i]))
continue;
if (pInputBuffer[i] &&
CheckCharacterValidity(pInputBuffer[i]) &&
pInputBuffer[i] != KEY_BACK &&
pInputBuffer[i] != KEY_RETURN &&
pInputBuffer[i] != KEY_ESCAPE)
{
if(StringLengthChar16(m_Text) < m_uMaxLength)
{
#if __BANK && UTF_16_SPEW
Displayf("Added character %x to text input string", pInputBuffer[i]);
#endif // __BANK && UTF_16_SPEW
ShiftArrayForward(m_uCursorLocation);
if(CTextFormat::IsUnsupportedSpace(pInputBuffer[i]))
m_Text[m_uCursorLocation] = ' ';
else
m_Text[m_uCursorLocation] = pInputBuffer[i];
m_uCursorLocation++;
}
}
}
if (IsActive() && CScaleformMgr::IsMovieActive(m_iMovieID))
{
if(ms_Movie.BeginMethod("UPDATE_INPUT"))
{
USES_CONVERSION;
const char* textToShow = WIDE_TO_UTF8(m_Text);
ms_Movie.AddParamString(textToShow, false);
ms_Movie.AddParam(m_uCursorLocation);
ms_Movie.EndMethod();
}
m_uLastInputTime = fwTimer::GetSystemTimeInMilliseconds();
}
#if __BANK
s_iInputBoxState = (int)m_eState;
#endif // __BANK
}
void CTextInputBox::Close()
{
ioKeyboard::SetKeyboardLayoutSwitchingEnable(false);
RemoveTextInputBoxMovie();
m_AcceptCallback = NullCallback;
m_DeclineCallback = NullCallback;
m_bAllowComma = false;
}
int CTextInputBox::GetButtonMaskIndex(InputType eButton)
{
switch(eButton) {
case INPUT_FRONTEND_ACCEPT:
return 0;
case INPUT_FRONTEND_CANCEL:
return 1;
// There appears to be two input for this button.
case INPUT_FRONTEND_RLEFT:
case INPUT_FRONTEND_X:
return 2;
// There appears to be two input for this button.
case INPUT_FRONTEND_RUP:
case INPUT_FRONTEND_Y:
return 3;
default:
//uiAssertf(0, "Unhandled eButton! I don't know what index '%s' belongs in!", parser_eInstructionButtons_Strings[eButton] );
return -1;
}
}
void CTextInputBox::SetInstructionalButtons(u64 iFlags, CScaleformMovieWrapper* pOverride /* = NULL */)
{
// if (iFlags != FE_WARNING_NONE)
{
CMenuButtonList ButtonsToUse;
ASSERT_ONLY(u64 iSanityField = 0;)
// for all the bits that are turned on
for(int i=0; iFlags; ++i, iFlags>>=1)
{
if( iFlags & 1 && i < ms_ButtonData.GetCount() && BIT_64(i) != FE_WARNING_NOSOUND)
{
ButtonsToUse.Add( ms_ButtonData[i] );
#if __ASSERT
int iIndex = GetButtonMaskIndex(ms_ButtonData[i].m_ButtonInput);
if( iIndex != -1 )
{
uiAssertf(!BIT_ISSET(iIndex, iSanityField), "Warning Screen was assigned button prompts with the same input! This simply will not work! Check your bitindices against frontend.xml/WarningScreen and try again!");
iSanityField |= BIT_64(iIndex);
}
#endif
}
}
// sort those into whatever order code says
ButtonsToUse.postLoad();
// buttons GOOOOO
ButtonsToUse.Draw( pOverride ? pOverride : &ms_Movie );
}
}
void CTextInputBox::CheckIncomingFunctions(atHashWithStringBank methodName, const GFxValue* args)
{
if (methodName == ATSTRINGHASH("CURSOR_LOCATION_CHANGED",0x4540bf03))
{
if (uiVerifyf(args[1].IsNumber(), "CURSOR_LOCATION_CHANGED params not compatible: %s", sfScaleformManager::GetTypeName(args[1])))
{
if(STextInputBox::IsInstantiated())
{
STextInputBox::GetInstance().SetCursorLocation((int)args[1].GetNumber());
}
}
}
}
void CTextInputBox::ClearInstructionalButtons(CScaleformMovieWrapper* pOverride /* = NULL */)
{
CMenuButtonList ButtonsToUse;
// remove any buttons that may already be there
ButtonsToUse.Reset();
ButtonsToUse.Draw( pOverride ? pOverride : &ms_Movie );
}
void CTextInputBox::Update()
{
STextInputBox::GetInstance().UpdateMenu();
}
void CTextInputBox::UpdateMenu()
{
PF_AUTO_PUSH_TIMEBAR("CTextInputBox UpdateMenu");
if (m_bActive && CScaleformMgr::IsMovieActive(m_iMovieID) && (!CWarningScreen::IsActive() || SReportMenu::GetInstance().IsActive()) )
{
if(CNewHud::UpdateImeText())
m_bImeTextInputHasFocus = true;
CControlMgr::GetMainPlayerControl(false).DisableAllInputs();
m_bCursorThisFrame = ((fwTimer::GetSystemTimeInMilliseconds() / 1000) % 2) == 0;
UpdateInput();
m_bCursorPreviousFrame = m_bCursorThisFrame;
bool const c_InputIsKeyboardMouse = CControlMgr::GetPlayerMappingControl().WasKeyboardMouseLastKnownSource();
if (c_InputIsKeyboardMouse != m_bLastInputKeyboard)
{
ClearInstructionalButtons();
CTextInputBox::SetInstructionalButtons(CControlMgr::GetPlayerMappingControl().WasKeyboardMouseLastKnownSource() ? FE_WARNING_OK | FE_WARNING_QUIT : FE_WARNING_OK_CANCEL);
}
m_bLastInputKeyboard = c_InputIsKeyboardMouse;
}
}
void CTextInputBox::Render()
{
STextInputBox::GetInstance().RenderMenu();
}
void CTextInputBox::RenderMenu()
{
if (IsActive() && CScaleformMgr::IsMovieActive(m_iMovieID))
{
GRC_ALLOC_SCOPE_AUTO_PUSH_POP();
grcStateBlock::SetRasterizerState(grcStateBlock::RS_NoBackfaceCull);
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_IgnoreDepth);
grcStateBlock::SetBlendState(grcStateBlock::BS_CompositeAlpha);
grcBindTexture(NULL);
grcBegin(drawTriStrip, 4);
grcColor4f(0.0f, 0.0f, 0.0f, 0.3f);
grcVertex2f(0.0f, 0.0f);
grcVertex2f(1.0f, 0.0f);
grcVertex2f(0.0f, 1.0f);
grcVertex2f(1.0f, 1.0f);
grcEnd();
// Reset stateblocks after drawing
grcStateBlock::SetRasterizerState(grcStateBlock::RS_Default);
grcStateBlock::SetDepthStencilState(grcStateBlock::DSS_Default);
grcStateBlock::SetBlendState(grcStateBlock::BS_Default);
CScaleformMgr::RenderMovie(m_iMovieID, 0.0f, true, false, 1.0f);
}
}
void CTextInputBox::LoadTextInputBoxMovie()
{
if (!m_bActive)
{
ms_Movie.CreateMovieAndWaitForLoad(SF_BASE_CLASS_GENERIC, TEXT_INPUT_BOX_MOVIE_NAME, Vector2(0.0f, 0.0f), Vector2(1.0f, 1.0f), true);
m_iMovieID = ms_Movie.GetMovieID();
CScaleformMgr::ForceMovieUpdateInstantly(ms_Movie.GetMovieID(), true);
CBusySpinner::RegisterInstructionalButtonMovie(ms_Movie.GetMovieID());
m_bActive = true;
}
}
void CTextInputBox::RemoveTextInputBoxMovie()
{
reportDisplayf("CTextInputBox::RemoveReportMovie");
if(CScaleformMgr::IsMovieActive(m_iMovieID))
{
ms_Movie.CallMethod("CLEANUP");
ms_Movie.RemoveMovie();
m_iMovieID = -1;
m_bActive = false;
CBusySpinner::UnregisterInstructionalButtonMovie(ms_Movie.GetMovieID()); // remove if it's a message on top of a message, and doesn't require this
}
}
bool CTextInputBox::UpdateInput()
{
if (!IsActive())
{
return false;
}
HandleInput();
return false;
}
void CTextInputBox::SetInvalidCharacters()
{
m_InvalidCharacters.clear();
const int MAX_FILE_NAME_OFFLIMIT_CHARS = 10;
const char16 INVALID_FILENAME_CHARS[MAX_FILE_NAME_OFFLIMIT_CHARS] = {0x3a, 0x2f, 0x5c, 0x7c, 0x2c, 0x22, 0x3f, 0x3c, 0x3e, 0};
// Control characters 0-31 are not supported in the below filters
const int FIRST_VALID_CHAR = 32; // Space
if (m_eTextType == ioVirtualKeyboard::kTextType_INVALID ||
m_eTextType == ioVirtualKeyboard::kTextType_DEFAULT ||
m_eTextType == ioVirtualKeyboard::kTextType_EMAIL ||
m_eTextType == ioVirtualKeyboard::kTextType_PASSWORD ||
m_eTextType == ioVirtualKeyboard::kTextType_ALPHABET ||
m_eTextType == ioVirtualKeyboard::kTextType_FILENAME)
{
for(int i = 0; i < FIRST_VALID_CHAR; ++i)
{
m_InvalidCharacters.PushAndGrow(char16(i));
}
}
if(m_eTextType == ioVirtualKeyboard::kTextType_FILENAME)
{
for(int i = 0; i < MAX_FILE_NAME_OFFLIMIT_CHARS; ++i)
{
if(m_bAllowComma && INVALID_FILENAME_CHARS[i] == 0x2c)
continue;
m_InvalidCharacters.PushAndGrow(INVALID_FILENAME_CHARS[i]);
}
}
}
void CTextInputBox::SetValidCharacters()
{
// TODO - Move all this defining to fwTextUtil so other systems can access our whitelist of characters
#define NUMERIC_CHARS L"0123456789"
#define ENGLISH_CHARS L"ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#define EXTENDED_CHARS L"ðÐǦŞǧŽžêÊæÆáóéñĄĆĘŁŃÓŚŹŻąćęłńśźż¥£æþÞýÝøØåŠĞğšÿŸЁёàâäãèêëïîìíôòöõœùûüúçßÀÁÄÂÃÉÈÊËÏÎÌÍÔÒÖÕŒÙÛÜÚÑǵАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯабвгдежзийклмнопрстуфхцчшщьыъэюяЁё₸₽"
#define KOREAN_CHARS L"가각간갇갈갉갊감갑값갓갔강갖갗같갚갛개객갠갤갬갭갯갰갱갸갹갼걀걋걍걔걘걜거걱건걷걸걺검겁것겄겅겆겉겊겋게겐겔겜겝겟겠겡겨격겪견겯결겸겹겻겼경곁계곈곌곕곗고곡곤곧골곪곬곯곰곱곳공곶과곽관괄괆괌괍괏광괘괜괠괩괬괭괴괵괸괼굄굅굇굉교굔굘굡굣구국군굳굴굵굶굻굼굽굿궁궂궈궉권궐궜궝궤궷귀귁귄귈귐귑귓규균귤그극근귿글긁금급긋긍긔기긱긴긷길긺김깁깃깅깆깊까깍깎깐깔깖깜깝깟깠깡깥깨깩깬깰깸깹깻깼깽꺄꺅꺌꺼꺽꺾껀껄껌껍껏껐껑께껙껜껨껫껭껴껸껼꼇꼈꼍꼐꼬꼭꼰꼲꼴꼼꼽꼿꽁꽂꽃꽈꽉꽐꽜꽝꽤꽥꽹꾀꾄꾈꾐꾑꾕꾜꾸꾹꾼꿀꿇꿈꿉꿋꿍꿎꿔꿜꿨꿩꿰꿱꿴꿸뀀뀁뀄뀌뀐뀔뀜뀝뀨끄끅끈끊끌끎끓끔끕끗끙끝끼끽낀낄낌낍낏낑나낙낚난낟날낡낢남납낫났낭낮낯낱낳내낵낸낼냄냅냇냈냉냐냑냔냘냠냥너넉넋넌널넒넓넘넙넛넜넝넣네넥넨넬넴넵넷넸넹녀녁년녈념녑녔녕녘녜녠노녹논놀놂놈놉놋농높놓놔놘놜놨뇌뇐뇔뇜뇝뇟뇨뇩뇬뇰뇹뇻뇽누눅눈눋눌눔눕눗눙눠눴눼뉘뉜뉠뉨뉩뉴뉵뉼늄늅늉느늑는늘늙늚늠늡늣능늦늪늬늰늴니닉닌닐닒님닙닛닝닢다닥닦단닫달닭닮닯닳담답닷닸당닺닻닿대댁댄댈댐댑댓댔댕댜더덕덖던덛덜덞덟덤덥덧덩덫덮데덱덴델뎀뎁뎃뎄뎅뎌뎐뎔뎠뎡뎨뎬도독돈돋돌돎돐돔돕돗동돛돝돠돤돨돼됐되된될됨됩됫됴두둑둔둘둠둡둣둥둬뒀뒈뒝뒤뒨뒬뒵뒷뒹듀듄듈듐듕드득든듣들듦듬듭듯등듸디딕딘딛딜딤딥딧딨딩딪따딱딴딸땀땁땃땄땅땋때땍땐땔땜땝땟땠땡떠떡떤떨떪떫떰떱떳떴떵떻떼떽뗀뗄뗌뗍뗏뗐뗑뗘뗬또똑똔똘똥똬똴뙈뙤뙨뚜뚝뚠뚤뚫뚬뚱뛔뛰뛴뛸뜀뜁뜅뜨뜩뜬뜯뜰뜸뜹뜻띄띈띌띔띕띠띤띨띰띱띳띵라락란랄람랍랏랐랑랒랖랗래랙랜랠램랩랫랬랭랴략랸럇량러럭런럴럼럽럿렀렁렇레렉렌렐렘렙렛렝려력련렬렴렵렷렸령례롄롑롓로록론롤롬롭롯롱롸롼뢍뢨뢰뢴뢸룀룁룃룅료룐룔룝룟룡루룩룬룰룸룹룻룽뤄뤘뤠뤼뤽륀륄륌륏륑류륙륜률륨륩륫륭르륵른를름릅릇릉릊릍릎리릭린릴림립릿링마막만많맏말맑맒맘맙맛망맞맡맣매맥맨맬맴맵맷맸맹맺먀먁먈먕머먹먼멀멂멈멉멋멍멎멓메멕멘멜멤멥멧멨멩며멱면멸몃몄명몇몌모목몫몬몰몲몸몹못몽뫄뫈뫘뫙뫼묀묄묍묏묑묘묜묠묩묫무묵묶문묻물묽묾뭄뭅뭇뭉뭍뭏뭐뭔뭘뭡뭣뭬뮈뮌뮐뮤뮨뮬뮴뮷므믄믈믐믓미믹민믿밀밂밈밉밋밌밍및밑바박밖밗반받발밝밞밟밤밥밧방밭배백밴밸뱀뱁뱃뱄뱅뱉뱌뱍뱐뱝버벅번벋벌벎범법벗벙벚베벡벤벧벨벰벱벳벴벵벼벽변별볍볏볐병볕볘볜보복볶본볼봄봅봇봉봐봔봤봬뵀뵈뵉뵌뵐뵘뵙뵤뵨부북분붇불붉붊붐붑붓붕붙붚붜붤붰붸뷔뷕뷘뷜뷩뷰뷴뷸븀븃븅브븍븐블븜븝븟비빅빈빌빎빔빕빗빙빚빛빠빡빤빨빪빰빱빳빴빵빻빼빽뺀뺄뺌뺍뺏뺐뺑뺘뺙뺨뻐뻑뻔뻗뻘뻠뻣뻤뻥뻬뼁뼈뼉뼘뼙뼛뼜뼝뽀뽁뽄뽈뽐뽑뽕뾔뾰뿅뿌뿍뿐뿔뿜뿟뿡쀼쁑쁘쁜쁠쁨쁩삐삑삔삘삠삡삣삥사삭삯산삳살삵삶삼삽삿샀상샅새색샌샐샘샙샛샜생샤샥샨샬샴샵샷샹섀섄섈섐섕서석섞섟선섣설섦섧섬섭섯섰성섶세섹센셀셈셉셋셌셍셔셕션셜셤셥셧셨셩셰셴셸솅소속솎손솔솖솜솝솟송솥솨솩솬솰솽쇄쇈쇌쇔쇗쇘쇠쇤쇨쇰쇱쇳쇼쇽숀숄숌숍숏숑수숙순숟술숨숩숫숭숯숱숲숴쉈쉐쉑쉔쉘쉠쉥쉬쉭쉰쉴쉼쉽쉿슁슈슉슐슘슛슝스슥슨슬슭슴습슷승시식신싣실싫심십싯싱싶싸싹싻싼쌀쌈쌉쌌쌍쌓쌔쌕쌘쌜쌤쌥쌨쌩썅써썩썬썰썲썸썹썼썽쎄쎈쎌쏀쏘쏙쏜쏟쏠쏢쏨쏩쏭쏴쏵쏸쐈쐐쐤쐬쐰쐴쐼쐽쑈쑤쑥쑨쑬쑴쑵쑹쒀쒔쒜쒸쒼쓩쓰쓱쓴쓸쓺쓿씀씁씌씐씔씜씨씩씬씰씸씹씻씽아악안앉<EC9588>
#define CHINESE_CHARS_1 L"一乙丁七乃九了二人儿入八几刀刁力匕十卜又三下丈上丫丸凡久么也乞于亡兀刃勺千叉口土士夕大女子孑孓寸小尢尸山川工己已巳巾干廾弋弓才丑丐不中丰丹之尹予云井互五亢仁什仃仆仇仍今介仄元允內六兮公冗凶分切刈勻勾勿化匹午升卅卞厄友及反壬天夫太夭孔少尤尺屯巴幻廿弔引心戈戶手扎支文斗斤方日曰月木欠止歹毋比毛氏水火爪父爻片牙牛犬王丙世丕且丘主乍乏乎以付仔仕他仗代令仙仞充兄冉冊冬凹出凸刊加功包匆北匝仟半卉卡占卯卮去可古右召叮叩叨叼司叵叫另只史叱台句叭叻四囚外央失奴奶孕它尼巨巧左市布平幼弁弘弗必戊打扔扒扑斥旦朮本未末札正母民氐永汁汀氾犯玄玉瓜瓦甘生用甩田由甲申疋白皮皿目矛矢石示禾穴立丞丟乒乓乩亙交亦亥仿伉伙伊伕伍伐休伏仲件任仰仳份企伋光兇兆先全共再冰列刑划刎刖劣匈匡匠印危吉吏同吊吐吁吋各向名合吃后吆吒因回囝圳地在圭圬圯圩夙多夷夸妄奸妃好她如妁字存宇守宅安寺尖屹州帆并年式弛忙忖戎戌戍成扣扛托收早旨旬旭曲曳有朽朴朱朵次此死氖汝汗汙江池汐汕污汛汍汎灰牟牝百竹米糸缶羊羽老考而耒耳聿肉肋肌臣自至臼舌舛舟艮色艾虫血行衣西阡串亨位住佇佗佞伴佛何估佐佑伽伺伸佃佔似但佣作你伯低伶余佝佈佚兌克免兵冶冷別判利刪刨劫助努劬匣即卵吝吭吞吾否呎吧呆呃吳呈呂君吩告吹吻吸吮吵吶吠吼呀吱含吟听囪困囤囫坊坑址坍均坎圾坐坏圻壯夾妝妒妨妞妣妙妖妍妤妓妊妥孝孜孚孛完宋宏尬局屁尿尾岐岑岔岌巫希序庇床廷弄弟彤形彷役忘忌志忍忱快忸忪戒我抄抗抖技扶抉扭把扼找批扳抒扯折扮投抓抑抆改攻攸旱更束李杏材村杜杖杞杉杆杠杓杗步每求汞沙沁沈沉沅沛汪決沐汰沌汨沖沒汽沃汲汾汴沆汶沍沔沘沂灶灼災灸牢牡牠狄狂玖甬甫男甸皂盯矣私秀禿究系罕肖肓肝肘肛肚育良芒芋芍見角言谷豆豕貝赤走足身車辛辰迂迆迅迄巡邑邢邪邦那酉釆里防阮阱阪阬並乖乳事些亞享京佯依侍佳使佬供例來侃佰併侈佩佻侖佾侏侑佺兔兒兕兩具其典冽函刻券刷刺到刮制剁劾劻卒協卓卑卦卷卸卹取叔受味呵咖呸咕咀呻呷咄咒咆呼咐呱呶和咚呢周咋命咎固垃坷坪坩坡坦坤坼夜奉奇奈奄奔妾妻委妹妮姑姆姐姍始姓姊妯妳姒姅孟孤季宗定官宜宙宛尚屈居屆岷岡岸岩岫岱岳帘帚帖帕帛帑幸庚店府底庖延弦弧弩往征彿彼忝忠忽念忿怏怔怯怵怖怪怕怡性怩怫怛或戕房戾所承拉拌拄抿拂抹拒招披拓拔拋拈抨抽押拐拙拇拍抵拚抱拘拖拗拆抬拎放斧於旺昔易昌昆昂明昀昏昕昊昇服朋杭枋枕東果杳杷枇枝林杯杰板枉松析杵枚枓杼杪杲欣武歧歿氓氛泣注泳沱泌泥河沽沾沼波沫法泓沸泄油況沮泗泅泱沿治泡泛泊沬泯泜泖泠炕炎炒炊炙爬爭爸版牧物狀狎狙狗狐玩玨玟玫玥甽疝疙疚的盂盲直知矽社祀祁秉秈空穹竺糾罔羌羋者肺肥肢肱股肫肩肴肪肯臥臾舍芳芝芙芭芽芟芹花芬芥芯芸芣芰芾芷虎虱初表軋迎返近邵邸邱邶采金長門阜陀阿阻附陂隹雨青非亟亭亮信侵侯便俠俑俏保促侶俘俟俊俗侮俐俄係俚俎俞侷兗冒冑冠剎剃削前剌剋則勇勉勃勁匍南卻厚叛咬哀咨哎哉咸咦咳哇哂咽咪品哄哈咯咫咱咻咩咧咿囿垂型垠垣垢城垮垓奕契奏奎奐姜姘姿姣姨娃姥姪姚姦威姻孩宣宦室客宥封屎屏屍屋峙峒巷帝帥帟幽庠度建弈弭彥很待徊律徇後徉怒思怠急怎怨恍恰恨恢恆恃恬恫恪恤扁拜挖按拼拭持拮拽指拱拷拯括拾拴挑挂政故斫施既春昭映昧是星昨昱昤曷柿染柱柔某柬架枯柵柩柯柄柑枴柚查枸柏柞柳枰柙柢柝柒歪殃殆段毒毗氟泉洋洲洪流津洌洱洞洗活洽派洶洛泵洹洧洸洩洮洵洎洫炫為炳炬炯炭炸炮炤爰牲牯牴狩狠狡玷珊玻玲珍珀玳<E78F80>
#define CHINESE_CHARS_2 L"ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ乂乜凵匚厂万丌乇亍囗兀屮彳丏冇与丮亓仂仉仈冘勼卬厹圠夃夬尐巿旡殳毌气爿丱丼仨仜仩仡仝仚刌匜卌圢圣夗夯宁宄尒尻屴屳帄庀庂忉戉扐氕氶汃氿氻犮犰玊禸肊阞伎优伬仵伔仱伀价伈伝伂伅伢伓伄仴伒冱刓刉刐劦匢匟卍厊吇囡囟圮圪圴夼妀奼妅奻奾奷奿孖尕尥屼屺屻屾巟幵庄异弚彴忕忔忏扜扞扤扡扦扢扙扠扚扥旯旮朾朹朸朻机朿朼朳氘汆汒汜汏汊汔汋汌灱牞犴犵玎甪癿穵网艸艼芀艽艿虍襾邙邗邘邛邔阢阤阠阣佖伻佢佉体佤伾佧佒佟佁佘伭伳伿佡冏冹刜刞刡劭劮匉卣卲厎厏吰吷吪呔呅吙吜吥吘吽呏呁吨吤呇囮囧囥坁坅坌坉坋坒夆奀妦妘妠妗妎妢妐妏妧妡宎宒尨尪岍岏岈岋岉岒岊岆岓岕巠帊帎庋庉庌庈庍弅弝彸彶忒忑忐忭忨忮忳忡忤忣忺忯忷忻怀忴戺抃抌抎抏抔抇扱扻扺扰抁抈扷扽扲扴攷旰旴旳旲旵杅杇杙杕杌杈杝杍杚杋毐氚汸汧汫沄沋沏汱汯汩沚汭沇沕沜汦汳汥汻沎灴灺牣犿犽狃狆狁犺狅玕玗玓玔玒町甹疔疕皁礽耴肕肙肐肒肜芐芏芅芎芑芓芊芃芄豸迉辿邟邡邥邞邧邠阰阨阯阭丳侘侅佽侀侇佶佴侉侄佷佌侗佪侚佹侁佸侐侜侔侞侒侂侕佫佮冞冼冾刵刲刳剆刱劼匊匋匼厒厔咇呿咁咑咂咈呫呺呾呥呬呴呦咍呯呡呠咘呣呧呤囷囹坯坲坭坫坱坰坶垀坵坻坳坴坢坽夌奅妵妺姏姎妲姌姁妶妼姃姖妱妽姀姈妴姇孢孥宓宕屇岮岤岠岵岯岨岬岟岣岭岢岪岧岝岥岶岰岦帗帔帙弨弢弣弤彔徂彾彽忞忥怭怦怙怲怋怴怊怗怳怚怞怬怢怍怐怮怓怑怌怉怜戔戽抭抴拑抾抪抶拊抮抳抯抻抩抰抸攽斨斻昉旼昄昒昈旻昃昋昍昅旽昑昐曶朊枅杬枎枒杶杻枘枆构杴枍枌杺枟枑枙枃杽极杸杹枔欥殀歾毞氝沓泬泫泮泙沶泔沭泧沷泐泂沺泃泆泭泲泒泝沴沊沝沀泞泀洰泍泇沰泹泏泩泑炔炘炅炓炆炄炑炖炂炚炃牪狖狋狘狉狜狒狔狚狌狑玤玡玭玦玢玠玬玝瓝瓨甿畀甾疌疘皯盳盱盰盵矸矼矹矻矺矷礿秅穸穻竻籵糽耵肏肮肣肸肵肭舠芠苀芫芚芘芛芵芧芮芼芞芺芴芨芡芩苂芤苃芶芢虰虯虭虮豖迒迋迓迍迖迕迗邲邴邯邳邰阹阽阼阺陃俍俅俓侲俉俋俁俔俜俙侻侳俛俇俖侺俀侹俬剄勀勂匽卼厗厖厙厘咺咡咭咥哏哃茍咷咮哖咶哅哆咠呰咼咢咾呲哞咰垵垞垟垤垌垗垝垛垔垘垏垙垥垚垕壴复奓姡姞姮娀姱姝姺姽姼姶姤姲姷姛姩姳姵姠姾姴姭宨峐峘峌峗峋峛峞峚峉峇峊峖峓峔峏峈峆峎峟峸巹帡帢帣帠帤庰庤庢庛庣庥弇弮彖徆怷怹恔恲恞恅恓恇恉恛恌恀恂恟怤恄恘恦恮扂扃拏挍挋拵挎挃拫拹挏挌拸拶挀挓挔拺挕拻拰敁敃斪斿昶昡昲昵昜昦昢昳昫昺昝昴昹昮朏朐柁柲柈枺柜枻柸柘柀枷柅柫柤柟枵柍枳柷柶柮柣柂枹柎柧柰枲柼柆柭柌枮柦柛柺柉柊柃柪柋欨殂殄殶毖毘毠氠氡洴洭洟洼洿洒洊泚洳洄洙洺洚洑洀洝浂洁洘洷洃洏浀洇洠洬洈洢洉洐炷炟炾炱炰炡炴炵炩牁牉牊牬牰牳牮狊狤狨狫狟狪狦狣玅珌珂珈珅玹玶玵玴珫玿珇玾珃珆玸珋瓬瓮甮畇畈疧疪癹盄眈眃眄眅眊盷盻盺矧矨砆砑砒砅砐砏砎砉砃砓祊祌祋祅祄秕种秏秖秎窀穾竑笀笁籺籸籹籿粀粁紃紈紁罘羑羍羾耇耎耏耔耷胘胇胠胑胈胂胐胅胣胙胜胊胕胉胏胗胦胍臿舡芔苙苾苹茇苨茀苕茺苫苖苴苬苡苲苵茌苻苶苰苪苤苠苺苳苭虷虴虼虳衁衎衧衪衩觓訄訇赲迣迡迮迠郱邽邿郕郅邾郇郋郈釔釓陔陏陑陓陊陎倞倅倇倓倢倰倛俵俴倳倷倬俶俷倗倜倠倧倵倯倱倎党冔冓凊凄凅凈凎剡剚剒剞剟剕剢勍匎厞唦哢唗唒哧哳哤唚哿唄唈哫唑唅哱唊哻哷哸哠唎唃唋圁圂埌堲埕埒垺埆垽垼垸垶垿埇埐垹埁夎奊娙娖娭娮娕娏娗娊娞娳宧宭宬尃屖屔峬峿峮峱峷崀峹帩帨庨庮庪庬弳弰彧恝恚恧恁悢悈悀悒悁悝悃悕<E68283>
#define JAPANESE_CHARS L"亜哀挨愛曖悪握圧扱宛嵐安案暗以衣位囲医依委威為畏胃尉異移萎偉椅彙意違維慰遺緯域育一壱逸茨芋引印因咽姻員院淫陰飲隠韻右宇羽雨唄鬱畝浦運雲永泳英映栄営詠影鋭衛易疫益液駅悦越謁閲円延沿炎怨宴媛援園煙猿遠鉛塩演縁艶汚王凹央応往押旺欧殴桜翁奥横岡屋億憶臆虞乙俺卸音恩温穏下化火加可仮何花佳価果河苛科架夏家荷華菓貨渦過嫁暇禍靴寡歌箇稼課蚊牙瓦我画芽賀雅餓介回灰会快戒改怪拐悔海界皆械絵開階塊楷解潰壊懐諧貝外劾害崖涯街慨蓋該概骸垣柿各角拡革格核殻郭覚較隔閣確獲嚇穫学岳楽額顎掛潟括活喝渇割葛滑褐轄且株釜鎌刈干刊甘汗缶完肝官冠巻看陥乾勘患貫寒喚堪換敢棺款間閑勧寛幹感漢慣管関歓監緩憾還館環簡観韓艦鑑丸含岸岩玩眼頑顔願企伎危机気岐希忌汽奇祈季紀軌既記起飢鬼帰基寄規亀喜幾揮期棋貴棄毀旗器畿輝機騎技宜偽欺義疑儀戯擬犠議菊吉喫詰却客脚逆虐九久及弓丘旧休吸朽臼求究泣急級糾宮救球給嗅窮牛去巨居拒拠挙虚許距魚御漁凶共叫狂京享供協況峡挟狭恐恭胸脅強教郷境橋矯鏡競響驚仰暁業凝曲局極玉巾斤均近金菌勤琴筋僅禁緊錦謹襟吟銀区句苦駆具惧愚空偶遇隅串屈掘窟熊繰君訓勲薫軍郡群兄刑形系径茎係型契計恵啓掲渓経蛍敬景軽傾携継詣慶憬稽憩警鶏芸迎鯨隙劇撃激桁欠穴血決結傑潔月犬件見券肩建研県倹兼剣拳軒健険圏堅検嫌献絹遣権憲賢謙鍵繭顕験懸元幻玄言弦限原現舷減源厳己戸古呼固股虎孤弧故枯個庫湖雇誇鼓錮顧五互午呉後娯悟碁語誤護口工公勾孔功巧広甲交光向后好江考行坑孝抗攻更効幸拘肯侯厚恒洪皇紅荒郊香候校耕航貢降高康控梗黄喉慌港硬絞項溝鉱構綱酵稿興衡鋼講購乞号合拷剛傲豪克告谷刻国黒穀酷獄骨駒込頃今困昆恨根婚混痕紺魂墾懇左佐沙査砂唆差詐鎖座挫才再災妻采砕宰栽彩採済祭斎細菜最裁債催塞歳載際埼在材剤財罪崎作削昨柵索策酢搾錯咲冊札刷刹拶殺察撮擦雑皿三山参桟蚕惨産傘散算酸賛残斬暫士子支止氏仕史司四市矢旨死糸至伺志私使刺始姉枝祉肢姿思指施師恣紙脂視紫詞歯嗣試詩資飼誌雌摯賜諮示字寺次耳自似児事侍治持時滋慈辞磁餌璽鹿式識軸七叱失室疾執湿嫉漆質実芝写社車舎者射捨赦斜煮遮謝邪蛇尺借酌釈爵若弱寂手主守朱取狩首殊珠酒腫種趣寿受呪授需儒樹収囚州舟秀周宗拾秋臭修袖終羞習週就衆集愁酬醜蹴襲十汁充住柔重従渋銃獣縦叔祝宿淑粛縮塾熟出述術俊春瞬旬巡盾准殉純循順準潤遵処初所書庶暑署緒諸女如助序叙徐除小升少召匠床抄肖尚招承昇松沼昭宵将消症祥称笑唱商渉章紹訟勝掌晶焼焦硝粧詔証象傷奨照詳彰障憧衝賞償礁鐘上丈冗条状乗城浄剰常情場畳蒸縄壌嬢錠譲醸色拭食植殖飾触嘱織職辱尻心申伸臣芯身辛侵信津神唇娠振浸真針深紳進森診寝慎新審震薪親人刃仁尽迅甚陣尋腎須図水吹垂炊帥粋衰推酔遂睡穂随髄枢崇数据杉裾寸瀬是井世正生成西声制姓征性青斉政星牲省凄逝清盛婿晴勢聖誠精製誓静請整醒税夕斥石赤昔析席脊隻惜戚責跡積績籍切折拙窃接設雪摂節説舌絶千川仙占先宣専泉浅洗染扇栓旋船戦煎羨腺詮践箋銭潜線遷選薦繊鮮全前善然禅漸膳繕狙阻祖租素措粗組疎訴塑遡礎双壮早争走奏相荘草送倉捜挿桑巣掃曹曽爽窓創喪痩葬装僧想層総遭槽踪操燥霜騒藻造像増憎蔵贈臓即束足促則息捉速側測俗族属賊続卒率存村孫尊損遜他多汰打妥唾堕惰駄太対体耐待怠胎退帯泰堆袋逮替貸隊滞態戴大代台第題滝宅択沢卓拓託濯諾濁但達脱奪棚誰丹旦担単炭胆探淡短嘆端綻誕鍛団男段断弾暖談壇地池<E59CB0><E6B1A0>
#define ASIAN_CHARS KOREAN_CHARS CHINESE_CHARS_1 CHINESE_CHARS_2 JAPANESE_CHARS
#define GAMERTAG_CHARS NUMERIC_CHARS ENGLISH_CHARS EXTENDED_CHARS ASIAN_CHARS
#define FILENAME_CHARS L"ABCDEFGHIKJLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" NUMERIC_CHARS L"_ ()&[]{}@'#£$%"
m_ValidCharacters.clear();
int iCount = 0;
wchar_t const * const c_charactersToCheck = m_eTextType == ioVirtualKeyboard::kTextType_FILENAME ? FILENAME_CHARS :
m_eTextType == ioVirtualKeyboard::kTextType_GAMERTAG ? GAMERTAG_CHARS :
m_eTextType == ioVirtualKeyboard::kTextType_NUMERIC ? NUMERIC_CHARS : NULL;
while( c_charactersToCheck && c_charactersToCheck[iCount] != '\0' )
{
m_ValidCharacters.PushAndGrow( c_charactersToCheck[iCount] );
iCount++;
}
}
bool CTextInputBox::CheckCharacterValidity(rage::char16 c)
{
switch(m_eTextType)
{
case ioVirtualKeyboard::kTextType_NUMERIC:
case ioVirtualKeyboard::kTextType_GAMERTAG:
return IsCharacterValid(c);
case ioVirtualKeyboard::kTextType_FILENAME:
case ioVirtualKeyboard::kTextType_INVALID:
case ioVirtualKeyboard::kTextType_DEFAULT:
case ioVirtualKeyboard::kTextType_EMAIL:
case ioVirtualKeyboard::kTextType_PASSWORD:
case ioVirtualKeyboard::kTextType_ALPHABET:
return !IsCharacterInvalid(c);
default:
return true;
}
}
bool CTextInputBox::IsCharacterValid(rage::char16 c)
{
for(int i = 0; i < m_ValidCharacters.size(); ++i)
{
if(m_ValidCharacters[i] == c)
{
return true;
}
}
return false;
}
bool CTextInputBox::IsCharacterInvalid(rage::char16 c)
{
if(!CTextFormat::IsValidDisplayCharacter(c))
return true;
for(int i = 0; i < m_InvalidCharacters.size(); ++i)
{
if(m_InvalidCharacters[i] == c)
{
return true;
}
}
return false;
}
void CTextInputBox::ShiftArrayBack(int iIndex)
{
for(int i = iIndex; i < m_uMaxLength; ++i)
{
m_Text[i] = m_Text[i+1];
}
}
void CTextInputBox::ShiftArrayForward(int iIndex)
{
for(int i = m_uMaxLength; i > iIndex; --i)
{
m_Text[i] = m_Text[i-1];
}
}
int CTextInputBox::StringLengthChar16(char16* str)
{
int iCount = 0;
while(str[iCount] != '\0')
{
iCount++;
}
return iCount;
}
void CTextInputBox::OnSignOut()
{
if(STextInputBox::GetInstance().IsActive())
{
STextInputBox::GetInstance().Close();
STextInputBox::GetInstance().DestroyState();
}
}
#if __BANK
void CTextInputBox::InitWidgets()
{
bkBank *pBank = BANKMGR.FindBank(UI_DEBUG_BANK_NAME);
if (!pBank) // create the bank if not found
{
pBank = &BANKMGR.CreateBank(UI_DEBUG_BANK_NAME);
}
if (pBank)
{
pBank->AddButton("Create Text Input Box widgets", &CTextInputBox::CreateBankWidgets);
}
}
void CTextInputBox::CreateBankWidgets()
{
bkBank *pBank = BANKMGR.FindBank(UI_DEBUG_BANK_NAME);
if(pBank)
{
pBank->PushGroup("Text Input Box");
{
pBank->AddText("Box Title", &s_pszDebugTitle[0], DEBUG_STRING_SIZE);
pBank->AddText("Box Description", &s_pszDebugDescription[0], DEBUG_STRING_SIZE);
pBank->AddText("Box Default Input", &s_pszDebugDefaultInput[0], DEBUG_STRING_SIZE);
pBank->AddButton("Open Text Input Box", &CTextInputBox::DebugOpen);
pBank->AddButton("Close Text Input Box", &CTextInputBox::DebugClose);
pBank->AddText("TextInputBoxState: ", &s_iInputBoxState);
}
pBank->PopGroup();
}
}
void CTextInputBox::DebugOpen()
{
ioVirtualKeyboard::Params params;
if(s_pszDebugTitle != NULL)
Utf8ToWide(s_pszDebugTitle16, s_pszDebugTitle, DEBUG_STRING_SIZE);
if(s_pszDebugDescription != NULL)
Utf8ToWide(s_pszDebugDescription16, s_pszDebugDescription, DEBUG_STRING_SIZE);
if(s_pszDebugDefaultInput != NULL)
Utf8ToWide(s_pszDebugDefaultInput16, s_pszDebugDefaultInput, DEBUG_STRING_SIZE);
params.m_Title = s_pszDebugTitle16;
params.m_Description = s_pszDebugDescription16;
params.m_InitialValue = s_pszDebugDefaultInput16;
STextInputBox::GetInstance().Open(params);
}
void CTextInputBox::DebugClose()
{
STextInputBox::GetInstance().Close();
}
#endif //__BANK
#endif // RSG_PC