aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp')
-rw-r--r--Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp215
1 files changed, 207 insertions, 8 deletions
diff --git a/Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp
index c29bac2d..5ef783d3 100644
--- a/Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp
+++ b/Minecraft.Client/Common/UI/UIScene_SignEntryMenu.cpp
@@ -13,11 +13,17 @@ UIScene_SignEntryMenu::UIScene_SignEntryMenu(int iPad, void *_initData, UILayer
// Setup all the Iggy references we need for this scene
initialiseMovie();
- SignEntryScreenInput* initData = (SignEntryScreenInput*)_initData;
+ SignEntryScreenInput* initData = static_cast<SignEntryScreenInput *>(_initData);
m_sign = initData->sign;
m_bConfirmed = false;
m_bIgnoreInput = false;
+ m_iSignCursorFrame = 0;
+#ifdef _WINDOWS64
+ m_iActiveDirectEditLine = -1;
+ m_bNeedsInitialEdit = true;
+ m_bSkipTickNav = false;
+#endif
m_buttonConfirm.init(app.GetString(IDS_DONE), eControl_Confirm);
m_labelMessage.init(app.GetString(IDS_EDIT_SIGN_MESSAGE));
@@ -53,6 +59,7 @@ UIScene_SignEntryMenu::UIScene_SignEntryMenu(int iPad, void *_initData, UILayer
UIScene_SignEntryMenu::~UIScene_SignEntryMenu()
{
+ m_sign->SetSelectedLine(-1);
m_parentLayer->removeComponent(eUIComponent_MenuBackground);
}
@@ -77,6 +84,79 @@ void UIScene_SignEntryMenu::tick()
{
UIScene::tick();
+#ifdef _WINDOWS64
+ // On first tick, auto-start editing line 1 if KBM is active (Java-style flow)
+ if (m_bNeedsInitialEdit)
+ {
+ m_bNeedsInitialEdit = false;
+ if (g_KBMInput.IsKBMActive())
+ {
+ SetFocusToElement(eControl_Line1);
+ m_iActiveDirectEditLine = 0;
+ m_textInputLines[0].beginDirectEdit(15);
+ }
+ }
+
+ // UP/DOWN navigation — must happen after tickDirectEdit (so typed chars are consumed)
+ // and before sign cursor update (so the cursor is correct for this frame's render)
+ // m_bSkipTickNav prevents double-processing when handleInput auto-started editing this frame
+ if (m_iActiveDirectEditLine >= 0 && !m_bSkipTickNav)
+ {
+ int navDir = 0;
+ if (g_KBMInput.IsKeyPressed(VK_DOWN)) navDir = 1;
+ else if (g_KBMInput.IsKeyPressed(VK_UP)) navDir = -1;
+
+ if (navDir != 0)
+ {
+ int newLine = m_iActiveDirectEditLine + navDir;
+ if (newLine >= eControl_Line1 && newLine <= eControl_Line4)
+ {
+ m_textInputLines[m_iActiveDirectEditLine].confirmDirectEdit();
+ SetFocusToElement(newLine);
+ m_iActiveDirectEditLine = newLine;
+ m_textInputLines[newLine].beginDirectEdit(15);
+ }
+ else if (navDir > 0)
+ {
+ m_textInputLines[m_iActiveDirectEditLine].confirmDirectEdit();
+ SetFocusToElement(eControl_Confirm);
+ m_iActiveDirectEditLine = -1;
+ }
+ }
+ }
+ m_bSkipTickNav = false;
+
+ if (m_iActiveDirectEditLine >= 0 && !m_textInputLines[m_iActiveDirectEditLine].isDirectEditing())
+ m_iActiveDirectEditLine = -1;
+#endif
+
+ // Blinking > text < cursor on the 3D sign
+ m_iSignCursorFrame++;
+ if (m_iSignCursorFrame / 6 % 2 == 0)
+ {
+#ifdef _WINDOWS64
+ if (m_iActiveDirectEditLine >= 0)
+ m_sign->SetSelectedLine(m_iActiveDirectEditLine);
+ else
+#endif
+ {
+ int focusedLine = -1;
+ for (int i = eControl_Line1; i <= eControl_Line4; i++)
+ {
+ if (controlHasFocus(i))
+ {
+ focusedLine = i;
+ break;
+ }
+ }
+ m_sign->SetSelectedLine(focusedLine);
+ }
+ }
+ else
+ {
+ m_sign->SetSelectedLine(-1);
+ }
+
if(m_bConfirmed)
{
m_bConfirmed = false;
@@ -95,9 +175,9 @@ void UIScene_SignEntryMenu::tick()
if (pMinecraft->level->isClientSide)
{
shared_ptr<MultiplayerLocalPlayer> player = pMinecraft->localplayers[m_iPad];
- if(player != NULL && player->connection && player->connection->isStarted())
+ if(player != nullptr && player->connection && player->connection->isStarted())
{
- player->connection->send( shared_ptr<SignUpdatePacket>( new SignUpdatePacket(m_sign->x, m_sign->y, m_sign->z, m_sign->IsVerified(), m_sign->IsCensored(), m_sign->GetMessages()) ) );
+ player->connection->send(std::make_shared<SignUpdatePacket>(m_sign->x, m_sign->y, m_sign->z, m_sign->IsVerified(), m_sign->IsCensored(), m_sign->GetMessages()));
}
}
ui.CloseUIScenes(m_iPad);
@@ -107,6 +187,9 @@ void UIScene_SignEntryMenu::tick()
void UIScene_SignEntryMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
{
if(m_bConfirmed || m_bIgnoreInput) return;
+#ifdef _WINDOWS64
+ if (isDirectEditBlocking()) { handled = true; return; }
+#endif
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
@@ -132,32 +215,125 @@ void UIScene_SignEntryMenu::handleInput(int iPad, int key, bool repeat, bool pre
#ifdef __ORBIS__
case ACTION_MENU_TOUCHPAD_PRESS:
#endif
+ sendInputToMovie(key, repeat, pressed, released);
+ handled = true;
+ break;
case ACTION_MENU_UP:
case ACTION_MENU_DOWN:
sendInputToMovie(key, repeat, pressed, released);
+#ifdef _WINDOWS64
+ // Auto-start editing if focus moved to a line (e.g. UP from Confirm)
+ if (g_KBMInput.IsKBMActive())
+ {
+ for (int i = eControl_Line1; i <= eControl_Line4; i++)
+ {
+ if (controlHasFocus(i))
+ {
+ m_iActiveDirectEditLine = i;
+ m_textInputLines[i].beginDirectEdit(15);
+ m_bSkipTickNav = true;
+ break;
+ }
+ }
+ }
+#endif
handled = true;
break;
}
}
+#ifdef _WINDOWS64
+void UIScene_SignEntryMenu::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
+{
+ for (int i = 0; i < 4; i++)
+ inputs.push_back(&m_textInputLines[i]);
+}
+
+void UIScene_SignEntryMenu::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
+{
+ int line = -1;
+ for (int i = 0; i < 4; i++)
+ {
+ if (input == &m_textInputLines[i]) { line = i; break; }
+ }
+ if (line != m_iActiveDirectEditLine) return;
+
+ if (result == UIControl_TextInput::eDirectEdit_Confirmed)
+ {
+ int newLine = line + 1;
+ if (newLine <= eControl_Line4)
+ {
+ SetFocusToElement(newLine);
+ m_iActiveDirectEditLine = newLine;
+ m_textInputLines[newLine].beginDirectEdit(15);
+ }
+ else
+ {
+ m_iActiveDirectEditLine = -1;
+ m_bConfirmed = true;
+ }
+ }
+ else if (result == UIControl_TextInput::eDirectEdit_Cancelled)
+ {
+ m_iActiveDirectEditLine = -1;
+ wstring temp = L"";
+ for (int j = 0; j < 4; j++)
+ m_sign->SetMessage(j, temp);
+ navigateBack();
+ ui.PlayUISFX(eSFX_Back);
+ }
+}
+
+bool UIScene_SignEntryMenu::handleMouseClick(F32 x, F32 y)
+{
+ if (m_iActiveDirectEditLine >= 0)
+ {
+ // During direct edit, only the Done button is clickable.
+ // Hit-test it manually — all other clicks are consumed but ignored.
+ m_buttonConfirm.UpdateControl();
+ S32 cx = m_buttonConfirm.getXPos();
+ S32 cy = m_buttonConfirm.getYPos();
+ S32 cw = m_buttonConfirm.getWidth();
+ S32 ch = m_buttonConfirm.getHeight();
+ if (cw > 0 && ch > 0 && x >= cx && x <= cx + cw && y >= cy && y <= cy + ch)
+ {
+ m_textInputLines[m_iActiveDirectEditLine].confirmDirectEdit();
+ m_iActiveDirectEditLine = -1;
+ m_bConfirmed = true;
+ }
+ return true;
+ }
+ return UIScene::handleMouseClick(x, y);
+}
+#endif
+
int UIScene_SignEntryMenu::KeyboardCompleteCallback(LPVOID lpParam,bool bRes)
{
- // 4J HEG - No reason to set value if keyboard was cancelled
- UIScene_SignEntryMenu *pClass=(UIScene_SignEntryMenu *)lpParam;
+ const auto pClass=static_cast<UIScene_SignEntryMenu *>(lpParam);
pClass->m_bIgnoreInput = false;
if (bRes)
{
+#ifdef _WINDOWS64
+ uint16_t pchText[128];
+ ZeroMemory(pchText, 128 * sizeof(uint16_t));
+ Win64_GetKeyboardText(pchText, 128);
+ pClass->m_textInputLines[pClass->m_iEditingLine].setLabel(reinterpret_cast<wchar_t *>(pchText));
+#else
uint16_t pchText[128];
ZeroMemory(pchText, 128 * sizeof(uint16_t) );
InputManager.GetText(pchText);
pClass->m_textInputLines[pClass->m_iEditingLine].setLabel((wchar_t *)pchText);
+#endif
}
return 0;
}
void UIScene_SignEntryMenu::handlePress(F64 controlId, F64 childId)
{
- switch((int)controlId)
+#ifdef _WINDOWS64
+ if (isDirectEditBlocking()) return;
+#endif
+ switch(static_cast<int>(controlId))
{
case eControl_Confirm:
{
@@ -169,7 +345,29 @@ void UIScene_SignEntryMenu::handlePress(F64 controlId, F64 childId)
case eControl_Line3:
case eControl_Line4:
{
- m_iEditingLine = (int)controlId;
+ m_iEditingLine = static_cast<int>(controlId);
+#ifdef _WINDOWS64
+ if (g_KBMInput.IsKBMActive())
+ {
+ // Only start editing from keyboard (Enter on focused line), not mouse clicks
+ if (!g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT))
+ {
+ m_iActiveDirectEditLine = m_iEditingLine;
+ m_textInputLines[m_iEditingLine].beginDirectEdit(15);
+ }
+ }
+ else
+ {
+ m_bIgnoreInput = true;
+ UIKeyboardInitData kbData;
+ kbData.title = app.GetString(IDS_SIGN_TITLE);
+ kbData.defaultText = m_textInputLines[m_iEditingLine].getLabel();
+ kbData.maxChars = 15;
+ kbData.callback = &UIScene_SignEntryMenu::KeyboardCompleteCallback;
+ kbData.lpParam = this;
+ ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData, eUILayer_Fullscreen, eUIGroup_Fullscreen);
+ }
+#else
m_bIgnoreInput = true;
#ifdef _XBOX_ONE
// 4J-PB - Xbox One uses the Windows virtual keyboard, and doesn't have the Xbox 360 Latin keyboard type, so we can't restrict the input set to alphanumeric. The closest we get is the emailSmtpAddress type.
@@ -186,7 +384,8 @@ void UIScene_SignEntryMenu::handlePress(F64 controlId, F64 childId)
break;
}
#else
- InputManager.RequestKeyboard(app.GetString(IDS_SIGN_TITLE),m_textInputLines[m_iEditingLine].getLabel(),(DWORD)m_iPad,15,&UIScene_SignEntryMenu::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Alphabet);
+ InputManager.RequestKeyboard(app.GetString(IDS_SIGN_TITLE),m_textInputLines[m_iEditingLine].getLabel(),static_cast<DWORD>(m_iPad),15,&UIScene_SignEntryMenu::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Alphabet);
+#endif
#endif
}
break;