mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
merge
This commit is contained in:
commit
86102e7cd6
|
|
@ -1486,12 +1486,26 @@ bool IUIScene_AbstractContainerMenu::handleKeyDown(int iPad, int iAction, bool b
|
|||
}
|
||||
break;
|
||||
case ACTION_MENU_UP:
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.WasMouseWheelConsumed())
|
||||
{
|
||||
handleAdditionalKeyPress(ACTION_MENU_OTHER_STICK_UP);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
//ui.PlayUISFX(eSFX_Focus);
|
||||
m_eCurrTapState = eTapStateUp;
|
||||
}
|
||||
break;
|
||||
case ACTION_MENU_DOWN:
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.WasMouseWheelConsumed())
|
||||
{
|
||||
handleAdditionalKeyPress(ACTION_MENU_OTHER_STICK_DOWN);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
//ui.PlayUISFX(eSFX_Focus);
|
||||
m_eCurrTapState = eTapStateDown;
|
||||
|
|
|
|||
|
|
@ -1099,13 +1099,7 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction)
|
|||
break;
|
||||
case ACTION_MENU_OTHER_STICK_DOWN:
|
||||
{
|
||||
int pageStep = TabSpec::rows;
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.WasMouseWheelConsumed())
|
||||
{
|
||||
pageStep = 1;
|
||||
}
|
||||
#endif
|
||||
int pageStep = 1;
|
||||
m_tabPage[m_curTab] += pageStep;
|
||||
if(m_tabPage[m_curTab] >= specs[m_curTab]->getPageCount())
|
||||
{
|
||||
|
|
@ -1119,13 +1113,7 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction)
|
|||
break;
|
||||
case ACTION_MENU_OTHER_STICK_UP:
|
||||
{
|
||||
int pageStep = TabSpec::rows;
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.WasMouseWheelConsumed())
|
||||
{
|
||||
pageStep = 1;
|
||||
}
|
||||
#endif
|
||||
int pageStep = 1;
|
||||
m_tabPage[m_curTab] -= pageStep;
|
||||
if(m_tabPage[m_curTab] < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ UIControl::UIControl()
|
|||
m_isVisible = true;
|
||||
m_bHidden = false;
|
||||
m_eControlType = eNoControl;
|
||||
m_id = -1;
|
||||
m_pParentPanel = NULL;
|
||||
}
|
||||
|
||||
bool UIControl::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName)
|
||||
|
|
|
|||
|
|
@ -38,12 +38,14 @@ protected:
|
|||
bool m_bHidden; // set by the Remove call
|
||||
|
||||
public:
|
||||
UIControl *m_pParentPanel; // set by UI_MAP_ELEMENT macro during mapElementsAndNames
|
||||
|
||||
void setControlType(eUIControlType eType) {m_eControlType=eType;}
|
||||
eUIControlType getControlType() {return m_eControlType;}
|
||||
void setId(int iID) { m_id=iID; }
|
||||
int getId() { return m_id; }
|
||||
UIScene * getParentScene() {return m_parentScene;}
|
||||
UIControl* getParentPanel() { return m_pParentPanel; }
|
||||
|
||||
protected:
|
||||
IggyValuePath m_iggyPath;
|
||||
|
|
@ -62,10 +64,8 @@ public:
|
|||
|
||||
virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName);
|
||||
void UpdateControl();
|
||||
#ifdef __PSVITA__
|
||||
void setHidden(bool bHidden) {m_bHidden=bHidden;}
|
||||
bool getHidden(void) {return m_bHidden;}
|
||||
#endif
|
||||
|
||||
IggyValuePath *getIggyValuePath();
|
||||
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ void UIControl_ButtonList::setButtonLabel(int iButtonId, const wstring &label)
|
|||
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie(), &result, getIggyValuePath(), m_funcSetButtonLabel, 2 , value );
|
||||
}
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
void UIControl_ButtonList::SetTouchFocus(S32 iX, S32 iY, bool bRepeat)
|
||||
{
|
||||
IggyDataValue result;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
void setButtonLabel(int iButtonId, const wstring &label);
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
void SetTouchFocus(S32 iX, S32 iY, bool bRepeat);
|
||||
bool CanTouchTrigger(S32 iX, S32 iY);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,6 +5,15 @@
|
|||
UIControl_TextInput::UIControl_TextInput()
|
||||
{
|
||||
m_bHasFocus = false;
|
||||
m_bHasCaret = false;
|
||||
m_bCaretChecked = false;
|
||||
#ifdef _WINDOWS64
|
||||
m_bDirectEditing = false;
|
||||
m_iCursorPos = 0;
|
||||
m_iCharLimit = 0;
|
||||
m_iDirectEditCooldown = 0;
|
||||
m_iCaretBlinkTimer = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UIControl_TextInput::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName)
|
||||
|
|
@ -16,6 +25,7 @@ bool UIControl_TextInput::setupControl(UIScene *scene, IggyValuePath *parent, co
|
|||
m_textName = registerFastName(L"text");
|
||||
m_funcChangeState = registerFastName(L"ChangeState");
|
||||
m_funcSetCharLimit = registerFastName(L"SetCharLimit");
|
||||
m_funcSetCaretIndex = registerFastName(L"SetCaretIndex");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
@ -81,3 +91,197 @@ void UIControl_TextInput::SetCharLimit(int iLimit)
|
|||
value[0].number = iLimit;
|
||||
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_funcSetCharLimit , 1 , value );
|
||||
}
|
||||
|
||||
void UIControl_TextInput::setCaretVisible(bool visible)
|
||||
{
|
||||
if (!m_parentScene || !m_parentScene->getMovie())
|
||||
return;
|
||||
|
||||
// Check once whether this SWF's FJ_TextInput actually has a m_mcCaret child.
|
||||
// IggyValuePathMakeNameRef always succeeds (creates a ref to undefined),
|
||||
// so we validate by trying to read a property from the resolved path.
|
||||
if (!m_bCaretChecked)
|
||||
{
|
||||
IggyValuePath caretPath;
|
||||
if (IggyValuePathMakeNameRef(&caretPath, getIggyValuePath(), "m_mcCaret"))
|
||||
{
|
||||
rrbool test = false;
|
||||
IggyResult res = IggyValueGetBooleanRS(&caretPath, m_nameVisible, NULL, &test);
|
||||
m_bHasCaret = (res == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bHasCaret = false;
|
||||
}
|
||||
m_bCaretChecked = true;
|
||||
}
|
||||
if (!m_bHasCaret)
|
||||
return;
|
||||
|
||||
IggyValuePath caretPath;
|
||||
if (IggyValuePathMakeNameRef(&caretPath, getIggyValuePath(), "m_mcCaret"))
|
||||
{
|
||||
IggyValueSetBooleanRS(&caretPath, m_nameVisible, NULL, visible);
|
||||
}
|
||||
}
|
||||
|
||||
void UIControl_TextInput::setCaretIndex(int index)
|
||||
{
|
||||
if (!m_parentScene || !m_parentScene->getMovie())
|
||||
return;
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[1];
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = index;
|
||||
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_funcSetCaretIndex , 1 , value );
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
|
||||
void UIControl_TextInput::beginDirectEdit(int charLimit)
|
||||
{
|
||||
const wchar_t* current = getLabel();
|
||||
m_editBuffer = current ? current : L"";
|
||||
m_textBeforeEdit = m_editBuffer;
|
||||
m_iCursorPos = (int)m_editBuffer.length();
|
||||
m_iCharLimit = charLimit;
|
||||
m_bDirectEditing = true;
|
||||
m_iDirectEditCooldown = 0;
|
||||
m_iCaretBlinkTimer = 0;
|
||||
g_KBMInput.ClearCharBuffer();
|
||||
setCaretVisible(true);
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
|
||||
UIControl_TextInput::EDirectEditResult UIControl_TextInput::tickDirectEdit()
|
||||
{
|
||||
if (m_iDirectEditCooldown > 0)
|
||||
m_iDirectEditCooldown--;
|
||||
|
||||
if (!m_bDirectEditing)
|
||||
{
|
||||
setCaretVisible(false);
|
||||
return eDirectEdit_Continue;
|
||||
}
|
||||
|
||||
// Enforce caret visibility and position every tick — setLabel() and Flash
|
||||
// focus changes can reset both at any time.
|
||||
setCaretVisible(true);
|
||||
setCaretIndex(m_iCursorPos);
|
||||
|
||||
// For SWFs without m_mcCaret, insert '_' at the cursor position.
|
||||
// All characters remain visible — '_' sits between them like a cursor.
|
||||
if (!m_bHasCaret)
|
||||
{
|
||||
wstring display = m_editBuffer;
|
||||
display.insert(m_iCursorPos, 1, L'_');
|
||||
setLabel(display.c_str());
|
||||
}
|
||||
|
||||
EDirectEditResult result = eDirectEdit_Continue;
|
||||
bool changed = false;
|
||||
|
||||
// Consume typed characters from the KBM buffer
|
||||
wchar_t ch;
|
||||
while (g_KBMInput.ConsumeChar(ch))
|
||||
{
|
||||
if (ch == 0x08) // Backspace
|
||||
{
|
||||
if (m_iCursorPos > 0)
|
||||
{
|
||||
m_editBuffer.erase(m_iCursorPos - 1, 1);
|
||||
m_iCursorPos--;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (ch == 0x0D) // Enter — confirm edit
|
||||
{
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 4;
|
||||
setLabel(m_editBuffer.c_str(), true);
|
||||
setCaretVisible(false);
|
||||
return eDirectEdit_Confirmed;
|
||||
}
|
||||
else if (m_iCharLimit <= 0 || (int)m_editBuffer.length() < m_iCharLimit)
|
||||
{
|
||||
m_editBuffer.insert(m_iCursorPos, 1, ch);
|
||||
m_iCursorPos++;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow keys, Home, End, Delete for cursor movement
|
||||
if (g_KBMInput.IsKeyPressed(VK_LEFT) && m_iCursorPos > 0)
|
||||
{
|
||||
m_iCursorPos--;
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
if (g_KBMInput.IsKeyPressed(VK_RIGHT) && m_iCursorPos < (int)m_editBuffer.length())
|
||||
{
|
||||
m_iCursorPos++;
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
if (g_KBMInput.IsKeyPressed(VK_HOME))
|
||||
{
|
||||
m_iCursorPos = 0;
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
if (g_KBMInput.IsKeyPressed(VK_END))
|
||||
{
|
||||
m_iCursorPos = (int)m_editBuffer.length();
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
if (g_KBMInput.IsKeyPressed(VK_DELETE) && m_iCursorPos < (int)m_editBuffer.length())
|
||||
{
|
||||
m_editBuffer.erase(m_iCursorPos, 1);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Escape — cancel edit and restore original text
|
||||
if (g_KBMInput.IsKeyPressed(VK_ESCAPE))
|
||||
{
|
||||
m_editBuffer = m_textBeforeEdit;
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 4;
|
||||
setLabel(m_editBuffer.c_str());
|
||||
setCaretVisible(false);
|
||||
return eDirectEdit_Cancelled;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (m_bHasCaret)
|
||||
{
|
||||
setLabel(m_editBuffer.c_str());
|
||||
setCaretIndex(m_iCursorPos);
|
||||
}
|
||||
// SWFs without caret: the cursor block above already updates the label every tick
|
||||
}
|
||||
|
||||
return eDirectEdit_Continue;
|
||||
}
|
||||
|
||||
void UIControl_TextInput::cancelDirectEdit()
|
||||
{
|
||||
if (m_bDirectEditing)
|
||||
{
|
||||
m_editBuffer = m_textBeforeEdit;
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 4;
|
||||
setLabel(m_editBuffer.c_str(), true);
|
||||
setCaretVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void UIControl_TextInput::confirmDirectEdit()
|
||||
{
|
||||
if (m_bDirectEditing)
|
||||
{
|
||||
m_bDirectEditing = false;
|
||||
setLabel(m_editBuffer.c_str(), true);
|
||||
setCaretVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,7 +6,20 @@ class UIControl_TextInput : public UIControl_Base
|
|||
{
|
||||
private:
|
||||
IggyName m_textName, m_funcChangeState, m_funcSetCharLimit;
|
||||
IggyName m_funcSetCaretIndex;
|
||||
bool m_bHasFocus;
|
||||
bool m_bHasCaret;
|
||||
bool m_bCaretChecked;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool m_bDirectEditing;
|
||||
wstring m_textBeforeEdit;
|
||||
wstring m_editBuffer;
|
||||
int m_iCursorPos;
|
||||
int m_iCharLimit;
|
||||
int m_iDirectEditCooldown;
|
||||
int m_iCaretBlinkTimer;
|
||||
#endif
|
||||
|
||||
public:
|
||||
UIControl_TextInput();
|
||||
|
|
@ -19,4 +32,24 @@ public:
|
|||
virtual void setFocus(bool focus);
|
||||
|
||||
void SetCharLimit(int iLimit);
|
||||
|
||||
void setCaretVisible(bool visible);
|
||||
void setCaretIndex(int index);
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
enum EDirectEditResult
|
||||
{
|
||||
eDirectEdit_Continue,
|
||||
eDirectEdit_Confirmed,
|
||||
eDirectEdit_Cancelled,
|
||||
};
|
||||
|
||||
void beginDirectEdit(int charLimit = 0);
|
||||
EDirectEditResult tickDirectEdit();
|
||||
void cancelDirectEdit();
|
||||
void confirmDirectEdit();
|
||||
bool isDirectEditing() const { return m_bDirectEditing; }
|
||||
int getDirectEditCooldown() const { return m_iDirectEditCooldown; }
|
||||
const wstring& getEditBuffer() const { return m_editBuffer; }
|
||||
#endif
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "UI.h"
|
||||
#include "UIScene.h"
|
||||
#include "UIControl_Slider.h"
|
||||
#include "UIControl_TexturePackList.h"
|
||||
#include "..\..\..\Minecraft.World\StringHelpers.h"
|
||||
#include "..\..\LocalPlayer.h"
|
||||
#include "..\..\DLCTexturePack.h"
|
||||
|
|
@ -237,6 +238,8 @@ UIController::UIController()
|
|||
m_winUserIndex = 0;
|
||||
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||
m_mouseDraggingSliderId = -1;
|
||||
m_mouseClickConsumedByScene = false;
|
||||
m_bMouseHoverHorizontalList = false;
|
||||
m_lastHoverMouseX = -1;
|
||||
m_lastHoverMouseY = -1;
|
||||
m_accumulatedTicks = 0;
|
||||
|
|
@ -784,40 +787,36 @@ void UIController::tickInput()
|
|||
#endif
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
m_mouseClickConsumedByScene = false;
|
||||
if (!g_KBMInput.IsMouseGrabbed() && g_KBMInput.IsKBMActive())
|
||||
{
|
||||
UIScene *pScene = NULL;
|
||||
for (int grp = 0; grp < eUIGroup_COUNT && !pScene; ++grp)
|
||||
// Search by layer priority across all groups (layer-first).
|
||||
// Tooltip layer is skipped because it holds non-interactive
|
||||
// overlays (button hints, timer) that should never capture mouse.
|
||||
// Old group-first order found those tooltips on eUIGroup_Fullscreen
|
||||
// before reaching in-game menus on eUIGroup_Player1.
|
||||
static const EUILayer mouseLayers[] = {
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
eUILayer_Debug,
|
||||
#endif
|
||||
eUILayer_Error,
|
||||
eUILayer_Alert,
|
||||
eUILayer_Popup,
|
||||
eUILayer_Fullscreen,
|
||||
eUILayer_Scene,
|
||||
};
|
||||
for (int l = 0; l < _countof(mouseLayers) && !pScene; ++l)
|
||||
{
|
||||
pScene = m_groups[grp]->GetTopScene(eUILayer_Debug);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Tooltips);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Error);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Alert);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Popup);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Fullscreen);
|
||||
if (!pScene) pScene = m_groups[grp]->GetTopScene(eUILayer_Scene);
|
||||
for (int grp = 0; grp < eUIGroup_COUNT && !pScene; ++grp)
|
||||
{
|
||||
pScene = m_groups[grp]->GetTopScene(mouseLayers[l]);
|
||||
}
|
||||
}
|
||||
if (pScene && pScene->getMovie())
|
||||
{
|
||||
Iggy *movie = pScene->getMovie();
|
||||
int rawMouseX = g_KBMInput.GetMouseX();
|
||||
int rawMouseY = g_KBMInput.GetMouseY();
|
||||
F32 mouseX = (F32)rawMouseX;
|
||||
F32 mouseY = (F32)rawMouseY;
|
||||
|
||||
extern HWND g_hWnd;
|
||||
if (g_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
int winW = rc.right - rc.left;
|
||||
int winH = rc.bottom - rc.top;
|
||||
if (winW > 0 && winH > 0)
|
||||
{
|
||||
mouseX = mouseX * (m_fScreenWidth / (F32)winW);
|
||||
mouseY = mouseY * (m_fScreenHeight / (F32)winH);
|
||||
}
|
||||
}
|
||||
|
||||
// Only update hover focus when the mouse has actually moved,
|
||||
// so that mouse-wheel scrolling can change list selection
|
||||
|
|
@ -826,43 +825,21 @@ void UIController::tickInput()
|
|||
m_lastHoverMouseX = rawMouseX;
|
||||
m_lastHoverMouseY = rawMouseY;
|
||||
|
||||
if (mouseMoved)
|
||||
// Convert mouse to scene/movie coordinates
|
||||
F32 sceneMouseX = (F32)rawMouseX;
|
||||
F32 sceneMouseY = (F32)rawMouseY;
|
||||
{
|
||||
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||
IggyFocusableObject focusables[64];
|
||||
S32 numFocusables = 0;
|
||||
IggyPlayerGetFocusableObjects(movie, ¤tFocus, focusables, 64, &numFocusables);
|
||||
|
||||
if (numFocusables > 0 && numFocusables <= 64)
|
||||
extern HWND g_hWnd;
|
||||
RECT rc;
|
||||
if (g_hWnd && GetClientRect(g_hWnd, &rc))
|
||||
{
|
||||
IggyFocusHandle hitObject = IGGY_FOCUS_NULL;
|
||||
for (S32 i = 0; i < numFocusables; ++i)
|
||||
int winW = rc.right - rc.left;
|
||||
int winH = rc.bottom - rc.top;
|
||||
if (winW > 0 && winH > 0)
|
||||
{
|
||||
if (mouseX >= focusables[i].x0 && mouseX <= focusables[i].x1 &&
|
||||
mouseY >= focusables[i].y0 && mouseY <= focusables[i].y1)
|
||||
{
|
||||
hitObject = focusables[i].object;
|
||||
break;
|
||||
}
|
||||
sceneMouseX = sceneMouseX * ((F32)pScene->getRenderWidth() / (F32)winW);
|
||||
sceneMouseY = sceneMouseY * ((F32)pScene->getRenderHeight() / (F32)winH);
|
||||
}
|
||||
|
||||
if (hitObject != currentFocus)
|
||||
{
|
||||
IggyPlayerSetFocusRS(movie, hitObject, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert mouse to scene/movie coordinates for slider hit testing
|
||||
F32 sceneMouseX = mouseX;
|
||||
F32 sceneMouseY = mouseY;
|
||||
{
|
||||
S32 displayWidth = 0, displayHeight = 0;
|
||||
pScene->GetParentLayer()->getRenderDimensions(displayWidth, displayHeight);
|
||||
if (displayWidth > 0 && displayHeight > 0)
|
||||
{
|
||||
sceneMouseX = mouseX * ((F32)pScene->getRenderWidth() / (F32)displayWidth);
|
||||
sceneMouseY = mouseY * ((F32)pScene->getRenderHeight() / (F32)displayHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -876,6 +853,110 @@ void UIController::tickInput()
|
|||
panelOffsetY = pMainPanel->getYPos();
|
||||
}
|
||||
|
||||
// Mouse hover — hit test against C++ control bounds.
|
||||
// Simple controls use SetFocusToElement; list controls
|
||||
// use their own SetTouchFocus for Flash-side hit testing.
|
||||
if (mouseMoved)
|
||||
{
|
||||
m_bMouseHoverHorizontalList = false;
|
||||
vector<UIControl *> *controls = pScene->GetControls();
|
||||
if (controls)
|
||||
{
|
||||
int hitControlId = -1;
|
||||
S32 hitArea = INT_MAX;
|
||||
UIControl *hitCtrl = NULL;
|
||||
for (size_t i = 0; i < controls->size(); ++i)
|
||||
{
|
||||
UIControl *ctrl = (*controls)[i];
|
||||
if (!ctrl || ctrl->getHidden() || !ctrl->getVisible() || ctrl->getId() < 0)
|
||||
continue;
|
||||
|
||||
UIControl::eUIControlType type = ctrl->getControlType();
|
||||
if (type != UIControl::eButton && type != UIControl::eTextInput &&
|
||||
type != UIControl::eCheckBox && type != UIControl::eSlider &&
|
||||
type != UIControl::eButtonList && type != UIControl::eTexturePackList)
|
||||
continue;
|
||||
|
||||
// If the scene has an active panel (e.g. tab menus),
|
||||
// skip controls that aren't children of that panel.
|
||||
if (pMainPanel && ctrl->getParentPanel() != pMainPanel)
|
||||
continue;
|
||||
|
||||
ctrl->UpdateControl();
|
||||
S32 cx = ctrl->getXPos() + panelOffsetX;
|
||||
S32 cy = ctrl->getYPos() + panelOffsetY;
|
||||
S32 cw = ctrl->getWidth();
|
||||
S32 ch = ctrl->getHeight();
|
||||
// TexturePackList origin is where the slot area starts,
|
||||
// not the top-left of the whole control — use GetRealHeight.
|
||||
if (type == UIControl::eTexturePackList)
|
||||
ch = ((UIControl_TexturePackList *)ctrl)->GetRealHeight();
|
||||
if (cw <= 0 || ch <= 0)
|
||||
continue;
|
||||
|
||||
if (sceneMouseX >= cx && sceneMouseX <= cx + cw &&
|
||||
sceneMouseY >= cy && sceneMouseY <= cy + ch)
|
||||
{
|
||||
if (type == UIControl::eButtonList)
|
||||
{
|
||||
// ButtonList manages focus internally via Flash —
|
||||
// pass mouse coords so it can highlight the right item.
|
||||
((UIControl_ButtonList *)ctrl)->SetTouchFocus(
|
||||
(S32)sceneMouseX, (S32)sceneMouseY, false);
|
||||
hitControlId = -1;
|
||||
hitArea = INT_MAX;
|
||||
hitCtrl = NULL;
|
||||
break; // ButtonList takes priority
|
||||
}
|
||||
if (type == UIControl::eTexturePackList)
|
||||
{
|
||||
// TexturePackList expects coords relative to its origin.
|
||||
UIControl_TexturePackList *pList = (UIControl_TexturePackList *)ctrl;
|
||||
pScene->SetFocusToElement(ctrl->getId());
|
||||
pList->SetTouchFocus(
|
||||
(S32)(sceneMouseX - cx), (S32)(sceneMouseY - cy), false);
|
||||
m_bMouseHoverHorizontalList = true;
|
||||
hitControlId = -1;
|
||||
hitArea = INT_MAX;
|
||||
hitCtrl = NULL;
|
||||
break;
|
||||
}
|
||||
S32 area = cw * ch;
|
||||
if (area < hitArea)
|
||||
{
|
||||
hitControlId = ctrl->getId();
|
||||
hitArea = area;
|
||||
hitCtrl = ctrl;
|
||||
if (type == UIControl::eSlider)
|
||||
m_bMouseHoverHorizontalList = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hitControlId >= 0 && pScene->getControlFocus() != hitControlId)
|
||||
{
|
||||
// During direct editing, don't let hover move focus
|
||||
// away to other TextInputs (e.g. sign lines).
|
||||
if (hitCtrl && hitCtrl->getControlType() == UIControl::eTextInput
|
||||
&& pScene->isDirectEditBlocking())
|
||||
{
|
||||
// Skip — keep focus on the actively-edited input
|
||||
}
|
||||
else
|
||||
{
|
||||
pScene->SetFocusToElement(hitControlId);
|
||||
// TextInput: SetFocusToElement triggers ChangeState which
|
||||
// shows the caret. Hide it immediately — the render pass
|
||||
// happens after both tickInput and scene tick, so no flicker.
|
||||
if (hitCtrl && hitCtrl->getControlType() == UIControl::eTextInput)
|
||||
{
|
||||
((UIControl_TextInput *)hitCtrl)->setCaretVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool leftPressed = g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT);
|
||||
bool leftDown = leftPressed || g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_LEFT);
|
||||
|
||||
|
|
@ -890,12 +971,51 @@ void UIController::tickInput()
|
|||
vector<UIControl *> *controls = pScene->GetControls();
|
||||
if (controls)
|
||||
{
|
||||
// Set Iggy dispatch focus for TextInput on click (not hover)
|
||||
// so ACTION_MENU_OK targets the correct text field.
|
||||
for (size_t i = 0; i < controls->size(); ++i)
|
||||
{
|
||||
UIControl *ctrl = (*controls)[i];
|
||||
if (!ctrl || ctrl->getControlType() != UIControl::eTextInput || !ctrl->getVisible())
|
||||
continue;
|
||||
if (pMainPanel && ctrl->getParentPanel() != pMainPanel)
|
||||
continue;
|
||||
ctrl->UpdateControl();
|
||||
S32 cx = ctrl->getXPos() + panelOffsetX;
|
||||
S32 cy = ctrl->getYPos() + panelOffsetY;
|
||||
S32 cw = ctrl->getWidth();
|
||||
S32 ch = ctrl->getHeight();
|
||||
if (cw > 0 && ch > 0 &&
|
||||
sceneMouseX >= cx && sceneMouseX <= cx + cw &&
|
||||
sceneMouseY >= cy && sceneMouseY <= cy + ch)
|
||||
{
|
||||
Iggy *movie = pScene->getMovie();
|
||||
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||
IggyFocusableObject focusables[64];
|
||||
S32 numFocusables = 0;
|
||||
IggyPlayerGetFocusableObjects(movie, ¤tFocus, focusables, 64, &numFocusables);
|
||||
for (S32 fi = 0; fi < numFocusables && fi < 64; ++fi)
|
||||
{
|
||||
if (sceneMouseX >= focusables[fi].x0 && sceneMouseX <= focusables[fi].x1 &&
|
||||
sceneMouseY >= focusables[fi].y0 && sceneMouseY <= focusables[fi].y1)
|
||||
{
|
||||
IggyPlayerSetFocusRS(movie, focusables[fi].object, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < controls->size(); ++i)
|
||||
{
|
||||
UIControl *ctrl = (*controls)[i];
|
||||
if (!ctrl || ctrl->getControlType() != UIControl::eSlider || !ctrl->getVisible())
|
||||
continue;
|
||||
|
||||
if (pMainPanel && ctrl->getParentPanel() != pMainPanel)
|
||||
continue;
|
||||
|
||||
UIControl_Slider *pSlider = (UIControl_Slider *)ctrl;
|
||||
pSlider->UpdateControl();
|
||||
S32 cx = pSlider->getXPos() + panelOffsetX;
|
||||
|
|
@ -942,6 +1062,12 @@ void UIController::tickInput()
|
|||
m_mouseDraggingSliderScene = eUIScene_COUNT;
|
||||
m_mouseDraggingSliderId = -1;
|
||||
}
|
||||
|
||||
// Let the scene handle mouse clicks for custom navigation (e.g. crafting slots)
|
||||
if (leftPressed && m_mouseDraggingSliderId < 0)
|
||||
{
|
||||
m_mouseClickConsumedByScene = pScene->handleMouseClick(sceneMouseX, sceneMouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1206,7 +1332,7 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
|||
|
||||
if ((key == ACTION_MENU_OK || key == ACTION_MENU_A) && !g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
if (m_mouseDraggingSliderId < 0)
|
||||
if (m_mouseDraggingSliderId < 0 && !m_mouseClickConsumedByScene)
|
||||
{
|
||||
if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT)) { pressed = true; down = true; }
|
||||
if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_LEFT)) { released = true; down = false; }
|
||||
|
|
@ -1214,6 +1340,14 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
|||
}
|
||||
}
|
||||
|
||||
// Right click → ACTION_MENU_X (pick up half stack in inventory)
|
||||
if (key == ACTION_MENU_X && !g_KBMInput.IsMouseGrabbed())
|
||||
{
|
||||
if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_RIGHT)) { pressed = true; down = true; }
|
||||
if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_RIGHT)) { released = true; down = false; }
|
||||
if (!pressed && !released && g_KBMInput.IsMouseButtonDown(KeyboardMouseInput::MOUSE_RIGHT)) { down = true; }
|
||||
}
|
||||
|
||||
// Scroll wheel for list scrolling — only consume the wheel value when the
|
||||
// action key actually matches, so the other direction isn't lost.
|
||||
if (!g_KBMInput.IsMouseGrabbed() && (key == ACTION_MENU_OTHER_STICK_UP || key == ACTION_MENU_OTHER_STICK_DOWN))
|
||||
|
|
@ -1231,6 +1365,16 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
|||
pressed = true;
|
||||
down = true;
|
||||
}
|
||||
|
||||
// Remap scroll wheel to navigation actions. Use LEFT/RIGHT when
|
||||
// hovering a horizontal list (e.g. TexturePackList), UP/DOWN otherwise.
|
||||
if (pressed && g_KBMInput.IsKBMActive())
|
||||
{
|
||||
if (m_bMouseHoverHorizontalList)
|
||||
key = (key == ACTION_MENU_OTHER_STICK_UP) ? ACTION_MENU_LEFT : ACTION_MENU_RIGHT;
|
||||
else
|
||||
key = (key == ACTION_MENU_OTHER_STICK_UP) ? ACTION_MENU_UP : ACTION_MENU_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ private:
|
|||
unsigned int m_winUserIndex;
|
||||
EUIScene m_mouseDraggingSliderScene;
|
||||
int m_mouseDraggingSliderId;
|
||||
bool m_mouseClickConsumedByScene;
|
||||
bool m_bMouseHoverHorizontalList;
|
||||
int m_lastHoverMouseX;
|
||||
int m_lastHoverMouseY;
|
||||
//bool m_bSysUIShowing;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ void UIScene::initialiseMovie()
|
|||
m_bUpdateOpacity = true;
|
||||
}
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
void UIScene::SetFocusToElement(int iID)
|
||||
{
|
||||
IggyDataValue result;
|
||||
|
|
@ -447,6 +447,19 @@ void UIScene::tick()
|
|||
IggyPlayerTickRS( swf );
|
||||
m_hasTickedOnce = true;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
{
|
||||
vector<UIControl_TextInput*> inputs;
|
||||
getDirectEditInputs(inputs);
|
||||
for (size_t i = 0; i < inputs.size(); i++)
|
||||
{
|
||||
UIControl_TextInput::EDirectEditResult result = inputs[i]->tickDirectEdit();
|
||||
if (result != UIControl_TextInput::eDirectEdit_Continue)
|
||||
onDirectEditFinished(inputs[i], result);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
UIControl* UIScene::GetMainPanel()
|
||||
|
|
@ -454,6 +467,113 @@ UIControl* UIScene::GetMainPanel()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool UIScene::isDirectEditBlocking()
|
||||
{
|
||||
vector<UIControl_TextInput*> inputs;
|
||||
getDirectEditInputs(inputs);
|
||||
for (size_t i = 0; i < inputs.size(); i++)
|
||||
{
|
||||
if (inputs[i]->isDirectEditing() || inputs[i]->getDirectEditCooldown() > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIScene::handleMouseClick(F32 x, F32 y)
|
||||
{
|
||||
S32 panelOffsetX = 0, panelOffsetY = 0;
|
||||
UIControl *pMainPanel = GetMainPanel();
|
||||
if (pMainPanel)
|
||||
{
|
||||
pMainPanel->UpdateControl();
|
||||
panelOffsetX = pMainPanel->getXPos();
|
||||
panelOffsetY = pMainPanel->getYPos();
|
||||
}
|
||||
|
||||
// Click-outside-to-deselect: confirm any active direct edit if
|
||||
// the click landed outside the editing text input.
|
||||
{
|
||||
vector<UIControl_TextInput*> deInputs;
|
||||
getDirectEditInputs(deInputs);
|
||||
for (size_t i = 0; i < deInputs.size(); i++)
|
||||
{
|
||||
if (!deInputs[i]->isDirectEditing())
|
||||
continue;
|
||||
deInputs[i]->UpdateControl();
|
||||
S32 cx = deInputs[i]->getXPos() + panelOffsetX;
|
||||
S32 cy = deInputs[i]->getYPos() + panelOffsetY;
|
||||
S32 cw = deInputs[i]->getWidth();
|
||||
S32 ch = deInputs[i]->getHeight();
|
||||
if (!(cw > 0 && ch > 0 && x >= cx && x <= cx + cw && y >= cy && y <= cy + ch))
|
||||
{
|
||||
deInputs[i]->confirmDirectEdit();
|
||||
onDirectEditFinished(deInputs[i], UIControl_TextInput::eDirectEdit_Confirmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<UIControl *> *controls = GetControls();
|
||||
if (!controls) return false;
|
||||
|
||||
// Hit-test controls and pick the smallest-area match to handle
|
||||
// overlapping Flash bounds correctly without sacrificing precision.
|
||||
int bestId = -1;
|
||||
S32 bestArea = INT_MAX;
|
||||
UIControl *bestCtrl = NULL;
|
||||
|
||||
for (size_t i = 0; i < controls->size(); ++i)
|
||||
{
|
||||
UIControl *ctrl = (*controls)[i];
|
||||
if (!ctrl || ctrl->getHidden() || !ctrl->getVisible() || ctrl->getId() < 0)
|
||||
continue;
|
||||
|
||||
UIControl::eUIControlType type = ctrl->getControlType();
|
||||
if (type != UIControl::eButton && type != UIControl::eTextInput &&
|
||||
type != UIControl::eCheckBox)
|
||||
continue;
|
||||
|
||||
if (pMainPanel && ctrl->getParentPanel() != pMainPanel)
|
||||
continue;
|
||||
|
||||
ctrl->UpdateControl();
|
||||
S32 cx = ctrl->getXPos() + panelOffsetX;
|
||||
S32 cy = ctrl->getYPos() + panelOffsetY;
|
||||
S32 cw = ctrl->getWidth();
|
||||
S32 ch = ctrl->getHeight();
|
||||
if (cw <= 0 || ch <= 0)
|
||||
continue;
|
||||
|
||||
if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch)
|
||||
{
|
||||
S32 area = cw * ch;
|
||||
if (area < bestArea)
|
||||
{
|
||||
bestArea = area;
|
||||
bestId = ctrl->getId();
|
||||
bestCtrl = ctrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestId >= 0 && bestCtrl)
|
||||
{
|
||||
if (bestCtrl->getControlType() == UIControl::eCheckBox)
|
||||
{
|
||||
UIControl_CheckBox *cb = (UIControl_CheckBox *)bestCtrl;
|
||||
bool newState = !cb->IsChecked();
|
||||
cb->setChecked(newState);
|
||||
handleCheckboxToggled((F64)bestId, newState);
|
||||
}
|
||||
else
|
||||
{
|
||||
handlePress((F64)bestId, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene::addTimer(int id, int ms)
|
||||
{
|
||||
|
|
@ -534,12 +654,13 @@ void UIScene::removeControl( UIControl_Base *control, bool centreScene)
|
|||
// update the button positions since they may have changed
|
||||
UpdateSceneControls();
|
||||
|
||||
// mark the button as removed
|
||||
control->setHidden(true);
|
||||
// remove it from the touchboxes
|
||||
ui.TouchBoxRebuild(control->getParentScene());
|
||||
#endif
|
||||
|
||||
// mark the button as removed so hover/touch hit-tests skip it
|
||||
control->setHidden(true);
|
||||
|
||||
}
|
||||
|
||||
void UIScene::slideLeft()
|
||||
|
|
@ -900,6 +1021,25 @@ void UIScene::sendInputToMovie(int key, bool repeat, bool pressed, bool released
|
|||
app.DebugPrintf("UI WARNING: Ignoring input as game action does not translate to an Iggy keycode\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
// If a navigation key is pressed with no focused element, focus the first
|
||||
// available one so arrow keys work even when the mouse is over empty space.
|
||||
if(pressed && (iggyKeyCode == IGGY_KEYCODE_UP || iggyKeyCode == IGGY_KEYCODE_DOWN ||
|
||||
iggyKeyCode == IGGY_KEYCODE_LEFT || iggyKeyCode == IGGY_KEYCODE_RIGHT))
|
||||
{
|
||||
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||
IggyFocusableObject focusables[64];
|
||||
S32 numFocusables = 0;
|
||||
IggyPlayerGetFocusableObjects(swf, ¤tFocus, focusables, 64, &numFocusables);
|
||||
if(currentFocus == IGGY_FOCUS_NULL && numFocusables > 0)
|
||||
{
|
||||
IggyPlayerSetFocusRS(swf, focusables[0].object, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
IggyEvent keyEvent;
|
||||
// 4J Stu - Keyloc is always standard as we don't care about shift/alt
|
||||
IggyMakeEventKey( &keyEvent, pressed?IGGY_KEYEVENT_Down:IGGY_KEYEVENT_Up, (IggyKeycode)iggyKeyCode, IGGY_KEYLOC_Standard );
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using namespace std;
|
|||
|
||||
#include "UIEnums.h"
|
||||
#include "UIControl_Base.h"
|
||||
#include "UIControl_TextInput.h"
|
||||
|
||||
class ItemRenderer;
|
||||
class UILayer;
|
||||
|
|
@ -16,22 +17,26 @@ class UILayer;
|
|||
virtual bool mapElementsAndNames() \
|
||||
{ \
|
||||
parentClass::mapElementsAndNames(); \
|
||||
IggyValuePath *currentRoot = IggyPlayerRootPath ( getMovie() );
|
||||
IggyValuePath *currentRoot = IggyPlayerRootPath ( getMovie() ); \
|
||||
UIControl *_mapPanel = NULL;
|
||||
|
||||
#define UI_END_MAP_ELEMENTS_AND_NAMES() \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define UI_MAP_ELEMENT( var, name) \
|
||||
{ var.setupControl(this, currentRoot , name ); m_controls.push_back(&var); }
|
||||
{ var.setupControl(this, currentRoot , name ); var.m_pParentPanel = _mapPanel; m_controls.push_back(&var); }
|
||||
|
||||
#define UI_BEGIN_MAP_CHILD_ELEMENTS( parent ) \
|
||||
{ \
|
||||
IggyValuePath *lastRoot = currentRoot; \
|
||||
currentRoot = parent.getIggyValuePath();
|
||||
UIControl *_lastPanel = _mapPanel; \
|
||||
currentRoot = parent.getIggyValuePath(); \
|
||||
_mapPanel = &parent;
|
||||
|
||||
#define UI_END_MAP_CHILD_ELEMENTS() \
|
||||
currentRoot = lastRoot; \
|
||||
_mapPanel = _lastPanel; \
|
||||
}
|
||||
|
||||
#define UI_MAP_NAME( var, name ) \
|
||||
|
|
@ -141,8 +146,10 @@ public:
|
|||
virtual void tick();
|
||||
|
||||
IggyName registerFastName(const wstring &name);
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
void SetFocusToElement(int iID);
|
||||
#endif
|
||||
#ifdef __PSVITA__
|
||||
void SetFocusToElement(int iID);
|
||||
void UpdateSceneControls();
|
||||
#endif
|
||||
protected:
|
||||
|
|
@ -177,6 +184,19 @@ public:
|
|||
// returns main panel if controls are not living in the root
|
||||
virtual UIControl* GetMainPanel();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
// Direct edit support: scenes override to register their text inputs.
|
||||
// Base class handles tickDirectEdit in tick(), click-outside-to-deselect
|
||||
// in handleMouseClick(), and provides isDirectEditBlocking() for guards.
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs) {}
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result) {}
|
||||
bool isDirectEditBlocking();
|
||||
|
||||
// Mouse click dispatch. Hit-tests C++ controls and picks the smallest-area
|
||||
// match, then calls handlePress. Override for custom behaviour (e.g. crafting).
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
#endif
|
||||
|
||||
void removeControl( UIControl_Base *control, bool centreScene);
|
||||
void slideLeft();
|
||||
void slideRight();
|
||||
|
|
|
|||
|
|
@ -96,6 +96,19 @@ void UIScene_AnvilMenu::tick()
|
|||
{
|
||||
UIScene_AbstractContainerMenu::tick();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
// Live update: sync item name per-keystroke while editing (like Java edition)
|
||||
if (m_textInputAnvil.isDirectEditing())
|
||||
{
|
||||
const wstring& buf = m_textInputAnvil.getEditBuffer();
|
||||
if (buf != m_itemName)
|
||||
{
|
||||
m_itemName = buf;
|
||||
updateItemName();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
handleTick();
|
||||
}
|
||||
|
||||
|
|
@ -306,26 +319,67 @@ UIControl *UIScene_AnvilMenu::getSection(ESceneSection eSection)
|
|||
return control;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
void UIScene_AnvilMenu::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
|
||||
{
|
||||
inputs.push_back(&m_textInputAnvil);
|
||||
}
|
||||
|
||||
void UIScene_AnvilMenu::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
|
||||
{
|
||||
m_itemName = input->getEditBuffer();
|
||||
updateItemName();
|
||||
}
|
||||
#endif
|
||||
|
||||
int UIScene_AnvilMenu::KeyboardCompleteCallback(LPVOID lpParam,bool bRes)
|
||||
{
|
||||
// 4J HEG - No reason to set value if keyboard was cancelled
|
||||
UIScene_AnvilMenu *pClass=(UIScene_AnvilMenu *)lpParam;
|
||||
pClass->setIgnoreInput(false);
|
||||
|
||||
if (bRes)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
uint16_t pchText[128];
|
||||
ZeroMemory(pchText, 128 * sizeof(uint16_t));
|
||||
Win64_GetKeyboardText(pchText, 128);
|
||||
pClass->setEditNameValue((wchar_t *)pchText);
|
||||
pClass->m_itemName = (wchar_t *)pchText;
|
||||
pClass->updateItemName();
|
||||
#else
|
||||
uint16_t pchText[128];
|
||||
ZeroMemory(pchText, 128 * sizeof(uint16_t) );
|
||||
InputManager.GetText(pchText);
|
||||
pClass->setEditNameValue((wchar_t *)pchText);
|
||||
pClass->m_itemName = (wchar_t *)pchText;
|
||||
pClass->updateItemName();
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UIScene_AnvilMenu::handleEditNamePressed()
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking())
|
||||
return;
|
||||
|
||||
if (g_KBMInput.IsKBMActive())
|
||||
{
|
||||
m_textInputAnvil.beginDirectEdit(30);
|
||||
}
|
||||
else
|
||||
{
|
||||
setIgnoreInput(true);
|
||||
UIKeyboardInitData kbData;
|
||||
kbData.title = app.GetString(IDS_TITLE_RENAME);
|
||||
kbData.defaultText = m_textInputAnvil.getLabel();
|
||||
kbData.maxChars = 30;
|
||||
kbData.callback = &UIScene_AnvilMenu::KeyboardCompleteCallback;
|
||||
kbData.lpParam = this;
|
||||
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData, eUILayer_Fullscreen, eUIGroup_Fullscreen);
|
||||
}
|
||||
#else
|
||||
setIgnoreInput(true);
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined __PSVITA__
|
||||
int language = XGetLanguage();
|
||||
|
|
@ -337,13 +391,13 @@ void UIScene_AnvilMenu::handleEditNamePressed()
|
|||
InputManager.RequestKeyboard(app.GetString(IDS_TITLE_RENAME),m_textInputAnvil.getLabel(),(DWORD)m_iPad,30,&UIScene_AnvilMenu::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
break;
|
||||
default:
|
||||
// 4J Stu - Use a different keyboard for non-asian languages so we don't have prediction on
|
||||
InputManager.RequestKeyboard(app.GetString(IDS_TITLE_RENAME),m_textInputAnvil.getLabel(),(DWORD)m_iPad,30,&UIScene_AnvilMenu::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Alphabet_Extended);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
InputManager.RequestKeyboard(app.GetString(IDS_TITLE_RENAME),m_textInputAnvil.getLabel(),(DWORD)m_iPad,30,&UIScene_AnvilMenu::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void UIScene_AnvilMenu::setEditNameValue(const wstring &name)
|
||||
|
|
@ -357,6 +411,8 @@ void UIScene_AnvilMenu::setEditNameEditable(bool enabled)
|
|||
|
||||
void UIScene_AnvilMenu::setCostLabel(const wstring &label, bool canAfford)
|
||||
{
|
||||
if (!getMovie()) return;
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[2];
|
||||
|
||||
|
|
@ -375,6 +431,8 @@ void UIScene_AnvilMenu::showCross(bool show)
|
|||
{
|
||||
if(m_showingCross != show)
|
||||
{
|
||||
if (!getMovie()) return;
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[1];
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ protected:
|
|||
|
||||
virtual UIControl *getSection(ESceneSection eSection);
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
#endif
|
||||
static int KeyboardCompleteCallback(LPVOID lpParam,bool bRes);
|
||||
virtual void handleEditNamePressed();
|
||||
virtual void setEditNameValue(const wstring &name);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include "..\..\MultiplayerLocalPlayer.h"
|
||||
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
||||
#include "UIScene_CraftingMenu.h"
|
||||
#ifdef _WINDOWS64
|
||||
#include "..\..\Windows64\Iggy\gdraw\gdraw_d3d11.h"
|
||||
#endif
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#define GAME_CRAFTING_TOUCHUPDATE_TIMER_ID 0
|
||||
|
|
@ -12,6 +15,11 @@
|
|||
|
||||
UIScene_CraftingMenu::UIScene_CraftingMenu(int iPad, void *_initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
m_hSlotBoundsValid = false;
|
||||
m_hSlotX0 = m_hSlotY0 = m_hSlotY1 = 0;
|
||||
m_hSlotSpacing = 0;
|
||||
#endif
|
||||
m_bIgnoreKeyPresses = false;
|
||||
|
||||
CraftingPanelScreenInput* initData = (CraftingPanelScreenInput*)_initData;
|
||||
|
|
@ -254,12 +262,14 @@ wstring UIScene_CraftingMenu::getMoviePath()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
UIControl* UIScene_CraftingMenu::GetMainPanel()
|
||||
{
|
||||
return &m_controlMainPanel;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __PSVITA__
|
||||
void UIScene_CraftingMenu::handleTouchInput(unsigned int iPad, S32 x, S32 y, int iId, bool bPressed, bool bRepeat, bool bReleased)
|
||||
{
|
||||
// perform action on release
|
||||
|
|
@ -383,6 +393,85 @@ void UIScene_CraftingMenu::handleTimerComplete(int id)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool UIScene_CraftingMenu::handleMouseClick(F32 x, F32 y)
|
||||
{
|
||||
if (!m_hSlotBoundsValid || m_hSlotSpacing <= 0)
|
||||
return false;
|
||||
|
||||
// Tab click — tabs sit directly above the H slot row. We derive their
|
||||
// bounds from the H slot positions cached in customDraw, since the Vita
|
||||
// TouchPanel controls are full-screen overlays with unusable bounds.
|
||||
int maxTabs = (m_iContainerType == RECIPE_TYPE_3x3) ? m_iMaxGroup3x3 : m_iMaxGroup2x2;
|
||||
F32 slotHeight = m_hSlotY1 - m_hSlotY0;
|
||||
F32 tabRowY0 = (m_hSlotY0 * 0.75f) - slotHeight * 1.55f;
|
||||
F32 tabRowY1 = tabRowY0 + (slotHeight * 1.7f);
|
||||
F32 tabRowWidth = m_hSlotSpacing * m_iCraftablesMaxHSlotC;
|
||||
F32 tabWidth = tabRowWidth / maxTabs;
|
||||
|
||||
if (tabWidth > 0 && x >= m_hSlotX0 && x < m_hSlotX0 + tabRowWidth &&
|
||||
y >= tabRowY0 && y < tabRowY1)
|
||||
{
|
||||
int iTab = (int)((x - m_hSlotX0) / tabWidth);
|
||||
if (iTab >= 0 && iTab < maxTabs && iTab != m_iGroupIndex)
|
||||
{
|
||||
showTabHighlight(m_iGroupIndex, false);
|
||||
m_iGroupIndex = iTab;
|
||||
showTabHighlight(m_iGroupIndex, true);
|
||||
m_iCurrentSlotHIndex = 0;
|
||||
m_iCurrentSlotVIndex = 1;
|
||||
CheckRecipesAvailable();
|
||||
iVSlotIndexA[0] = CanBeMadeA[m_iCurrentSlotHIndex].iCount - 1;
|
||||
iVSlotIndexA[1] = 0;
|
||||
iVSlotIndexA[2] = 1;
|
||||
ui.PlayUISFX(eSFX_Focus);
|
||||
UpdateVerticalSlots();
|
||||
UpdateHighlight();
|
||||
setGroupText(GetGroupNameText(m_pGroupA[m_iGroupIndex]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// H slot click — select or craft
|
||||
F32 rowWidth = m_hSlotSpacing * m_iCraftablesMaxHSlotC;
|
||||
if (x >= m_hSlotX0 && x < m_hSlotX0 + rowWidth &&
|
||||
y >= m_hSlotY0 && y < m_hSlotY1)
|
||||
{
|
||||
int iNewSlot = (int)((x - m_hSlotX0) / m_hSlotSpacing);
|
||||
if (iNewSlot >= 0 && iNewSlot < m_iCraftablesMaxHSlotC)
|
||||
{
|
||||
// Only interact with populated slots
|
||||
if (CanBeMadeA[iNewSlot].iCount == 0)
|
||||
return true;
|
||||
|
||||
if (iNewSlot == m_iCurrentSlotHIndex)
|
||||
{
|
||||
// Click on already-selected slot — craft the item
|
||||
handleKeyDown(m_iPad, ACTION_MENU_A, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int iOldHSlot = m_iCurrentSlotHIndex;
|
||||
m_iCurrentSlotHIndex = iNewSlot;
|
||||
m_iCurrentSlotVIndex = 1;
|
||||
iVSlotIndexA[0] = CanBeMadeA[m_iCurrentSlotHIndex].iCount - 1;
|
||||
iVSlotIndexA[1] = 0;
|
||||
iVSlotIndexA[2] = 1;
|
||||
UpdateVerticalSlots();
|
||||
UpdateHighlight();
|
||||
if (CanBeMadeA[iOldHSlot].iCount > 0)
|
||||
setShowCraftHSlot(iOldHSlot, true);
|
||||
ui.PlayUISFX(eSFX_Focus);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Consume all mouse clicks so misses don't generate ACTION_MENU_A
|
||||
// and accidentally craft. Only blocks mouse-originated presses.
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_CraftingMenu::handleReload()
|
||||
{
|
||||
m_slotListInventory.addSlots(CRAFTING_INVENTORY_SLOT_START,CRAFTING_INVENTORY_SLOT_END - CRAFTING_INVENTORY_SLOT_START);
|
||||
|
|
@ -478,6 +567,32 @@ void UIScene_CraftingMenu::customDraw(IggyCustomDrawCallbackRegion *region)
|
|||
{
|
||||
decorations = false;
|
||||
int iIndex = slotId - CRAFTING_H_SLOT_START;
|
||||
#ifdef _WINDOWS64
|
||||
// Cache H slot SWF-space positions from the custom draw transform matrix
|
||||
if (iIndex == 0 || iIndex == 1)
|
||||
{
|
||||
F32 mat[16];
|
||||
gdraw_D3D11_CalculateCustomDraw_4J(region, mat);
|
||||
// Matrix to SWF coords (same formula as setupCustomDrawMatrices)
|
||||
F32 sw = (F32)getRenderWidth();
|
||||
F32 sh = (F32)getRenderHeight();
|
||||
F32 swfX = sw * (1.0f + mat[3]) / 2.0f;
|
||||
F32 swfY = sh * (1.0f - mat[7]) / 2.0f;
|
||||
if (iIndex == 0)
|
||||
{
|
||||
m_hSlotX0 = swfX;
|
||||
m_hSlotY0 = swfY;
|
||||
// Slot visual height from matrix scale and region height
|
||||
F32 slotH = sh * (-mat[5]) / 2.0f * region->y1;
|
||||
m_hSlotY1 = swfY + slotH;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hSlotSpacing = swfX - m_hSlotX0;
|
||||
m_hSlotBoundsValid = (m_hSlotSpacing > 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(m_hSlotsInfo[iIndex].show)
|
||||
{
|
||||
item = m_hSlotsInfo[iIndex].item;
|
||||
|
|
|
|||
|
|
@ -66,10 +66,19 @@ public:
|
|||
|
||||
#ifdef __PSVITA__
|
||||
virtual void handleTouchInput(unsigned int iPad, S32 x, S32 y, int iId, bool bPressed, bool bRepeat, bool bReleased);
|
||||
virtual UIControl* GetMainPanel();
|
||||
virtual void handleTouchBoxRebuild();
|
||||
virtual void handleTimerComplete(int id);
|
||||
#endif
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
virtual UIControl* GetMainPanel();
|
||||
#endif
|
||||
#ifdef _WINDOWS64
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
// Cached from customDraw — H slot bounding boxes in SWF space
|
||||
F32 m_hSlotX0, m_hSlotY0, m_hSlotY1;
|
||||
F32 m_hSlotSpacing; // x distance between slot 0 and slot 1
|
||||
bool m_hSlotBoundsValid;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
UIControl m_controlMainPanel;
|
||||
|
|
@ -97,7 +106,7 @@ protected:
|
|||
ETouchInput_TouchPanel_5,
|
||||
ETouchInput_TouchPanel_6,
|
||||
ETouchInput_CraftingHSlots,
|
||||
|
||||
|
||||
ETouchInput_Count,
|
||||
};
|
||||
UIControl_Touch m_TouchInput[ETouchInput_Count];
|
||||
|
|
|
|||
|
|
@ -84,10 +84,6 @@ UIScene_CreateWorldMenu::UIScene_CreateWorldMenu(int iPad, void *initData, UILay
|
|||
m_iGameModeId = GameType::SURVIVAL->getId();
|
||||
m_pDLCPack = NULL;
|
||||
m_bRebuildTouchBoxes = false;
|
||||
#ifdef _WINDOWS64
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 0;
|
||||
#endif
|
||||
|
||||
m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
|
||||
// 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it.
|
||||
|
|
@ -293,53 +289,6 @@ void UIScene_CreateWorldMenu::tick()
|
|||
{
|
||||
UIScene::tick();
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (m_iDirectEditCooldown > 0)
|
||||
m_iDirectEditCooldown--;
|
||||
|
||||
if (m_bDirectEditing)
|
||||
{
|
||||
wchar_t ch;
|
||||
bool changed = false;
|
||||
while (g_KBMInput.ConsumeChar(ch))
|
||||
{
|
||||
if (ch == 0x08) // backspace
|
||||
{
|
||||
if (!m_worldName.empty())
|
||||
{
|
||||
m_worldName.pop_back();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (ch == 0x0D) // enter - confirm
|
||||
{
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 4; // absorb the matching ACTION_MENU_OK that follows
|
||||
m_editWorldName.setLabel(m_worldName.c_str());
|
||||
}
|
||||
else if ((int)m_worldName.length() < 25)
|
||||
{
|
||||
m_worldName += ch;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Escape cancels and restores the original name
|
||||
if (m_bDirectEditing && g_KBMInput.IsKeyPressed(VK_ESCAPE))
|
||||
{
|
||||
m_worldName = m_worldNameBeforeEdit;
|
||||
m_bDirectEditing = false;
|
||||
m_iDirectEditCooldown = 4;
|
||||
m_editWorldName.setLabel(m_worldName.c_str());
|
||||
m_buttonCreateWorld.setEnable(!m_worldName.empty());
|
||||
}
|
||||
else if (changed)
|
||||
{
|
||||
m_editWorldName.setLabel(m_worldName.c_str());
|
||||
m_buttonCreateWorld.setEnable(!m_worldName.empty());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(m_iSetTexturePackDescription >= 0 )
|
||||
{
|
||||
|
|
@ -403,11 +352,24 @@ int UIScene_CreateWorldMenu::ContinueOffline(void *pParam,int iPad,C4JStorage::E
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
void UIScene_CreateWorldMenu::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
|
||||
{
|
||||
inputs.push_back(&m_editWorldName);
|
||||
}
|
||||
|
||||
void UIScene_CreateWorldMenu::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
|
||||
{
|
||||
m_worldName = input->getEditBuffer();
|
||||
m_buttonCreateWorld.setEnable(!m_worldName.empty());
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_CreateWorldMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
{
|
||||
if(m_bIgnoreInput) return;
|
||||
#ifdef _WINDOWS64
|
||||
if (m_bDirectEditing || m_iDirectEditCooldown > 0) { handled = true; return; }
|
||||
if (isDirectEditBlocking()) { handled = true; return; }
|
||||
#endif
|
||||
|
||||
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
|
||||
|
|
@ -464,7 +426,7 @@ void UIScene_CreateWorldMenu::handlePress(F64 controlId, F64 childId)
|
|||
{
|
||||
if(m_bIgnoreInput) return;
|
||||
#ifdef _WINDOWS64
|
||||
if (m_bDirectEditing || m_iDirectEditCooldown > 0) return;
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
|
||||
//CD - Added for audio
|
||||
|
|
@ -476,7 +438,7 @@ void UIScene_CreateWorldMenu::handlePress(F64 controlId, F64 childId)
|
|||
{
|
||||
m_bIgnoreInput=true;
|
||||
#ifdef _WINDOWS64
|
||||
if (Win64_IsControllerConnected())
|
||||
if (!g_KBMInput.IsKBMActive())
|
||||
{
|
||||
UIKeyboardInitData kbData;
|
||||
kbData.title = app.GetString(IDS_CREATE_NEW_WORLD);
|
||||
|
|
@ -488,11 +450,8 @@ void UIScene_CreateWorldMenu::handlePress(F64 controlId, F64 childId)
|
|||
}
|
||||
else
|
||||
{
|
||||
// PC without controller: edit the name field directly in-place.
|
||||
m_bIgnoreInput = false; // Don't block input - m_bDirectEditing is the guard
|
||||
m_worldNameBeforeEdit = m_worldName;
|
||||
m_bDirectEditing = true;
|
||||
g_KBMInput.ClearCharBuffer();
|
||||
m_bIgnoreInput = false;
|
||||
m_editWorldName.beginDirectEdit(25);
|
||||
}
|
||||
#else
|
||||
InputManager.RequestKeyboard(app.GetString(IDS_CREATE_NEW_WORLD),m_editWorldName.getLabel(),(DWORD)0,25,&UIScene_CreateWorldMenu::KeyboardCompleteWorldNameCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
|
|
|
|||
|
|
@ -51,11 +51,6 @@ private:
|
|||
DLCPack * m_pDLCPack;
|
||||
bool m_bRebuildTouchBoxes;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
bool m_bDirectEditing;
|
||||
wstring m_worldNameBeforeEdit;
|
||||
int m_iDirectEditCooldown;
|
||||
#endif
|
||||
|
||||
public:
|
||||
UIScene_CreateWorldMenu(int iPad, void *initData, UILayer *parentLayer);
|
||||
|
|
@ -83,6 +78,10 @@ protected:
|
|||
public:
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void StartSharedLaunchFlow();
|
||||
|
|
|
|||
|
|
@ -41,8 +41,72 @@ wstring UIScene_DebugCreateSchematic::getMoviePath()
|
|||
return L"DebugCreateSchematic";
|
||||
}
|
||||
|
||||
UIControl_TextInput* UIScene_DebugCreateSchematic::getTextInputForControl(eControls ctrl)
|
||||
{
|
||||
switch (ctrl)
|
||||
{
|
||||
case eControl_Name: return &m_textInputName;
|
||||
case eControl_StartX: return &m_textInputStartX;
|
||||
case eControl_StartY: return &m_textInputStartY;
|
||||
case eControl_StartZ: return &m_textInputStartZ;
|
||||
case eControl_EndX: return &m_textInputEndX;
|
||||
case eControl_EndY: return &m_textInputEndY;
|
||||
case eControl_EndZ: return &m_textInputEndZ;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
void UIScene_DebugCreateSchematic::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
|
||||
{
|
||||
inputs.push_back(&m_textInputName);
|
||||
inputs.push_back(&m_textInputStartX);
|
||||
inputs.push_back(&m_textInputStartY);
|
||||
inputs.push_back(&m_textInputStartZ);
|
||||
inputs.push_back(&m_textInputEndX);
|
||||
inputs.push_back(&m_textInputEndY);
|
||||
inputs.push_back(&m_textInputEndZ);
|
||||
}
|
||||
|
||||
void UIScene_DebugCreateSchematic::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
|
||||
{
|
||||
wstring value = input->getEditBuffer();
|
||||
int iVal = 0;
|
||||
if (!value.empty())
|
||||
iVal = _fromString<int>(value);
|
||||
|
||||
if (input == &m_textInputName)
|
||||
{
|
||||
if (!value.empty())
|
||||
swprintf(m_data->name, 64, L"%ls", value.c_str());
|
||||
else
|
||||
swprintf(m_data->name, 64, L"schematic");
|
||||
}
|
||||
else if (input == &m_textInputStartX) m_data->startX = iVal;
|
||||
else if (input == &m_textInputStartY) m_data->startY = iVal;
|
||||
else if (input == &m_textInputStartZ) m_data->startZ = iVal;
|
||||
else if (input == &m_textInputEndX) m_data->endX = iVal;
|
||||
else if (input == &m_textInputEndY) m_data->endY = iVal;
|
||||
else if (input == &m_textInputEndZ) m_data->endZ = iVal;
|
||||
}
|
||||
|
||||
bool UIScene_DebugCreateSchematic::handleMouseClick(F32 x, F32 y)
|
||||
{
|
||||
UIScene::handleMouseClick(x, y);
|
||||
return true; // always consume to prevent Iggy re-entry on empty space
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_DebugCreateSchematic::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
}
|
||||
|
||||
void UIScene_DebugCreateSchematic::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
|
||||
|
||||
switch(key)
|
||||
|
|
@ -67,6 +131,9 @@ void UIScene_DebugCreateSchematic::handleInput(int iPad, int key, bool repeat, b
|
|||
|
||||
void UIScene_DebugCreateSchematic::handlePress(F64 controlId, F64 childId)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
switch((int)controlId)
|
||||
{
|
||||
case eControl_Create:
|
||||
|
|
@ -112,8 +179,28 @@ void UIScene_DebugCreateSchematic::handlePress(F64 controlId, F64 childId)
|
|||
case eControl_EndX:
|
||||
case eControl_EndY:
|
||||
case eControl_EndZ:
|
||||
m_keyboardCallbackControl = (eControls)((int)controlId);
|
||||
InputManager.RequestKeyboard(L"Enter something",L"",(DWORD)0,25,&UIScene_DebugCreateSchematic::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
{
|
||||
m_keyboardCallbackControl = (eControls)((int)controlId);
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.IsKBMActive())
|
||||
{
|
||||
UIControl_TextInput* input = getTextInputForControl(m_keyboardCallbackControl);
|
||||
if (input) input->beginDirectEdit(25);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIKeyboardInitData kbData;
|
||||
kbData.title = L"Enter something";
|
||||
kbData.defaultText = L"";
|
||||
kbData.maxChars = 25;
|
||||
kbData.callback = &UIScene_DebugCreateSchematic::KeyboardCompleteCallback;
|
||||
kbData.lpParam = this;
|
||||
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData, eUILayer_Fullscreen, eUIGroup_Fullscreen);
|
||||
}
|
||||
#else
|
||||
InputManager.RequestKeyboard(L"Enter something",L"",(DWORD)0,25,&UIScene_DebugCreateSchematic::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
|
@ -138,9 +225,15 @@ int UIScene_DebugCreateSchematic::KeyboardCompleteCallback(LPVOID lpParam,bool b
|
|||
{
|
||||
UIScene_DebugCreateSchematic *pClass=(UIScene_DebugCreateSchematic *)lpParam;
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
uint16_t pchText[128];
|
||||
ZeroMemory(pchText, 128 * sizeof(uint16_t));
|
||||
Win64_GetKeyboardText(pchText, 128);
|
||||
#else
|
||||
uint16_t pchText[128];
|
||||
ZeroMemory(pchText, 128 * sizeof(uint16_t) );
|
||||
InputManager.GetText(pchText);
|
||||
#endif
|
||||
|
||||
if(pchText[0]!=0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ private:
|
|||
|
||||
ConsoleSchematicFile::XboxSchematicInitParam *m_data;
|
||||
|
||||
|
||||
public:
|
||||
UIScene_DebugCreateSchematic(int iPad, void *initData, UILayer *parentLayer);
|
||||
|
||||
|
|
@ -58,8 +59,14 @@ protected:
|
|||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
||||
virtual wstring getMoviePath();
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual void tick();
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
|
||||
|
|
@ -68,6 +75,7 @@ protected:
|
|||
virtual void handleCheckboxToggled(F64 controlId, bool selected);
|
||||
|
||||
private:
|
||||
UIControl_TextInput* getTextInputForControl(eControls ctrl);
|
||||
static int KeyboardCompleteCallback(LPVOID lpParam,const bool bRes);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -31,19 +31,19 @@ UIScene_DebugSetCamera::UIScene_DebugSetCamera(int iPad, void *initData, UILayer
|
|||
|
||||
WCHAR TempString[256];
|
||||
|
||||
swprintf( (WCHAR *)TempString, 256, L"%f", currentPosition->m_camX);
|
||||
swprintf( (WCHAR *)TempString, 256, L"%.2f", currentPosition->m_camX);
|
||||
m_textInputX.init(TempString, eControl_CamX);
|
||||
|
||||
swprintf( (WCHAR *)TempString, 256, L"%f", currentPosition->m_camY);
|
||||
swprintf( (WCHAR *)TempString, 256, L"%.2f", currentPosition->m_camY);
|
||||
m_textInputY.init(TempString, eControl_CamY);
|
||||
|
||||
swprintf( (WCHAR *)TempString, 256, L"%f", currentPosition->m_camZ);
|
||||
swprintf( (WCHAR *)TempString, 256, L"%.2f", currentPosition->m_camZ);
|
||||
m_textInputZ.init(TempString, eControl_CamZ);
|
||||
|
||||
swprintf( (WCHAR *)TempString, 256, L"%f", currentPosition->m_yRot);
|
||||
swprintf( (WCHAR *)TempString, 256, L"%.2f", currentPosition->m_yRot);
|
||||
m_textInputYRot.init(TempString, eControl_YRot);
|
||||
|
||||
swprintf( (WCHAR *)TempString, 256, L"%f", currentPosition->m_elev);
|
||||
swprintf( (WCHAR *)TempString, 256, L"%.2f", currentPosition->m_elev);
|
||||
m_textInputElevation.init(TempString, eControl_Elevation);
|
||||
|
||||
m_checkboxLockPlayer.init(L"Lock Player", eControl_LockPlayer, app.GetFreezePlayers());
|
||||
|
|
@ -55,6 +55,7 @@ UIScene_DebugSetCamera::UIScene_DebugSetCamera(int iPad, void *initData, UILayer
|
|||
m_labelCamY.init(L"CamY");
|
||||
m_labelCamZ.init(L"CamZ");
|
||||
m_labelYRotElev.init(L"Y-Rot & Elevation (Degs)");
|
||||
|
||||
}
|
||||
|
||||
wstring UIScene_DebugSetCamera::getMoviePath()
|
||||
|
|
@ -62,8 +63,59 @@ wstring UIScene_DebugSetCamera::getMoviePath()
|
|||
return L"DebugSetCamera";
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
UIControl_TextInput* UIScene_DebugSetCamera::getTextInputForControl(eControls ctrl)
|
||||
{
|
||||
switch (ctrl)
|
||||
{
|
||||
case eControl_CamX: return &m_textInputX;
|
||||
case eControl_CamY: return &m_textInputY;
|
||||
case eControl_CamZ: return &m_textInputZ;
|
||||
case eControl_YRot: return &m_textInputYRot;
|
||||
case eControl_Elevation: return &m_textInputElevation;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void UIScene_DebugSetCamera::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
|
||||
{
|
||||
inputs.push_back(&m_textInputX);
|
||||
inputs.push_back(&m_textInputY);
|
||||
inputs.push_back(&m_textInputZ);
|
||||
inputs.push_back(&m_textInputYRot);
|
||||
inputs.push_back(&m_textInputElevation);
|
||||
}
|
||||
|
||||
void UIScene_DebugSetCamera::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
|
||||
{
|
||||
wstring value = input->getEditBuffer();
|
||||
double val = 0;
|
||||
if (!value.empty()) val = _fromString<double>(value);
|
||||
|
||||
if (input == &m_textInputX) currentPosition->m_camX = val;
|
||||
else if (input == &m_textInputY) currentPosition->m_camY = val;
|
||||
else if (input == &m_textInputZ) currentPosition->m_camZ = val;
|
||||
else if (input == &m_textInputYRot) currentPosition->m_yRot = val;
|
||||
else if (input == &m_textInputElevation) currentPosition->m_elev = val;
|
||||
}
|
||||
|
||||
bool UIScene_DebugSetCamera::handleMouseClick(F32 x, F32 y)
|
||||
{
|
||||
UIScene::handleMouseClick(x, y);
|
||||
return true; // always consume to prevent Iggy re-entry on empty space
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_DebugSetCamera::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
}
|
||||
|
||||
void UIScene_DebugSetCamera::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) { handled = true; return; }
|
||||
#endif
|
||||
ui.AnimateKeyPress(iPad, key, repeat, pressed, released);
|
||||
|
||||
switch(key)
|
||||
|
|
@ -88,11 +140,14 @@ void UIScene_DebugSetCamera::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
|
||||
void UIScene_DebugSetCamera::handlePress(F64 controlId, F64 childId)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
switch((int)controlId)
|
||||
{
|
||||
case eControl_Teleport:
|
||||
app.SetXuiServerAction( ProfileManager.GetPrimaryPad(),
|
||||
eXuiServerAction_SetCameraLocation,
|
||||
eXuiServerAction_SetCameraLocation,
|
||||
(void *)currentPosition);
|
||||
break;
|
||||
case eControl_CamX:
|
||||
|
|
@ -100,8 +155,26 @@ void UIScene_DebugSetCamera::handlePress(F64 controlId, F64 childId)
|
|||
case eControl_CamZ:
|
||||
case eControl_YRot:
|
||||
case eControl_Elevation:
|
||||
m_keyboardCallbackControl = (eControls)((int)controlId);
|
||||
m_keyboardCallbackControl = (eControls)((int)controlId);
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.IsKBMActive())
|
||||
{
|
||||
UIControl_TextInput* input = getTextInputForControl(m_keyboardCallbackControl);
|
||||
if (input) input->beginDirectEdit(25);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIKeyboardInitData kbData;
|
||||
kbData.title = L"Enter value";
|
||||
kbData.defaultText = L"";
|
||||
kbData.maxChars = 25;
|
||||
kbData.callback = &UIScene_DebugSetCamera::KeyboardCompleteCallback;
|
||||
kbData.lpParam = this;
|
||||
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData, eUILayer_Fullscreen, eUIGroup_Fullscreen);
|
||||
}
|
||||
#else
|
||||
InputManager.RequestKeyboard(L"Enter something",L"",(DWORD)0,25,&UIScene_DebugSetCamera::KeyboardCompleteCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
#endif
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
|
@ -119,9 +192,13 @@ void UIScene_DebugSetCamera::handleCheckboxToggled(F64 controlId, bool selected)
|
|||
int UIScene_DebugSetCamera::KeyboardCompleteCallback(LPVOID lpParam,bool bRes)
|
||||
{
|
||||
UIScene_DebugSetCamera *pClass=(UIScene_DebugSetCamera *)lpParam;
|
||||
uint16_t pchText[2048];//[128];
|
||||
ZeroMemory(pchText, 2048/*128*/ * sizeof(uint16_t) );
|
||||
uint16_t pchText[2048];
|
||||
ZeroMemory(pchText, 2048 * sizeof(uint16_t));
|
||||
#ifdef _WINDOWS64
|
||||
Win64_GetKeyboardText(pchText, 2048);
|
||||
#else
|
||||
InputManager.GetText(pchText);
|
||||
#endif
|
||||
|
||||
if(pchText[0]!=0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ private:
|
|||
FreezePlayerParam *fpp;
|
||||
|
||||
eControls m_keyboardCallbackControl;
|
||||
#ifdef _WINDOWS64
|
||||
UIControl_TextInput* getTextInputForControl(eControls ctrl);
|
||||
#endif
|
||||
|
||||
public:
|
||||
UIScene_DebugSetCamera(int iPad, void *initData, UILayer *parentLayer);
|
||||
|
|
@ -54,6 +57,12 @@ protected:
|
|||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
||||
virtual wstring getMoviePath();
|
||||
virtual void tick();
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
#endif
|
||||
|
||||
public:
|
||||
// INPUT
|
||||
|
|
|
|||
|
|
@ -753,7 +753,7 @@ void UIScene_HUD::handleTimerComplete(int id)
|
|||
float opacity = pGui->getOpacity(m_iPad, i);
|
||||
if( opacity > 0 )
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
#if 0 // def _WINDOWS64 // Use Iggy chat until Gui::render has visual parity
|
||||
// Chat drawn by Gui::render with color codes. Hides Iggy chat to avoid double chats.
|
||||
m_controlLabelBackground[i].setOpacity(0);
|
||||
m_labelChatText[i].setOpacity(0);
|
||||
|
|
|
|||
|
|
@ -163,6 +163,12 @@ void UIScene_Keyboard::tick()
|
|||
{
|
||||
UIScene::tick();
|
||||
|
||||
// Sync our buffer from Flash so we pick up changes made via controller/on-screen buttons.
|
||||
// Without this, switching between controller and keyboard would use stale text.
|
||||
const wchar_t* flashText = m_KeyboardTextInput.getLabel();
|
||||
if (flashText)
|
||||
m_win64TextBuffer = flashText;
|
||||
|
||||
// Accumulate physical keyboard chars into our own buffer, then push to Flash via setLabel.
|
||||
// This bypasses Iggy's focus system (char events only route to the focused element).
|
||||
// The char buffer is cleared on open so Enter/clicks from the triggering action don't leak in.
|
||||
|
|
|
|||
|
|
@ -257,6 +257,9 @@ void UIScene_LaunchMoreOptionsMenu::handleDestroy()
|
|||
void UIScene_LaunchMoreOptionsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
{
|
||||
if(m_bIgnoreInput) return;
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
|
||||
//app.DebugPrintf("UIScene_DebugOverlay handling input for pad %d, key %d, down- %s, pressed- %s, released- %s\n", iPad, key, down?"TRUE":"FALSE", pressed?"TRUE":"FALSE", released?"TRUE":"FALSE");
|
||||
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
|
||||
|
|
@ -334,7 +337,9 @@ void UIScene_LaunchMoreOptionsMenu::handleTouchInput(unsigned int iPad, S32 x, S
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
UIControl* UIScene_LaunchMoreOptionsMenu::GetMainPanel()
|
||||
{
|
||||
if(m_tabIndex == 0)
|
||||
|
|
@ -546,11 +551,16 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(LPVOID lpParam,b
|
|||
{
|
||||
UIScene_LaunchMoreOptionsMenu *pClass=(UIScene_LaunchMoreOptionsMenu *)lpParam;
|
||||
pClass->m_bIgnoreInput=false;
|
||||
// 4J HEG - No reason to set value if keyboard was cancelled
|
||||
if (bRes)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
uint16_t pchText[128];
|
||||
ZeroMemory(pchText, 128 * sizeof(uint16_t));
|
||||
Win64_GetKeyboardText(pchText, 128);
|
||||
pClass->m_editSeed.setLabel((wchar_t *)pchText);
|
||||
pClass->m_params->seed = (wchar_t *)pchText;
|
||||
#else
|
||||
#ifdef __PSVITA__
|
||||
//CD - Changed to 2048 [SCE_IME_MAX_TEXT_LENGTH]
|
||||
uint16_t pchText[2048];
|
||||
ZeroMemory(pchText, 2048 * sizeof(uint16_t) );
|
||||
#else
|
||||
|
|
@ -560,18 +570,52 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(LPVOID lpParam,b
|
|||
InputManager.GetText(pchText);
|
||||
pClass->m_editSeed.setLabel((wchar_t *)pchText);
|
||||
pClass->m_params->seed = (wchar_t *)pchText;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
void UIScene_LaunchMoreOptionsMenu::getDirectEditInputs(vector<UIControl_TextInput*> &inputs)
|
||||
{
|
||||
inputs.push_back(&m_editSeed);
|
||||
}
|
||||
|
||||
void UIScene_LaunchMoreOptionsMenu::onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result)
|
||||
{
|
||||
if (result == UIControl_TextInput::eDirectEdit_Confirmed)
|
||||
m_params->seed = input->getEditBuffer();
|
||||
}
|
||||
#endif
|
||||
|
||||
void UIScene_LaunchMoreOptionsMenu::handlePress(F64 controlId, F64 childId)
|
||||
{
|
||||
if(m_bIgnoreInput) return;
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
|
||||
switch((int)controlId)
|
||||
{
|
||||
case eControl_EditSeed:
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (g_KBMInput.IsKBMActive())
|
||||
{
|
||||
m_editSeed.beginDirectEdit(60);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bIgnoreInput = true;
|
||||
UIKeyboardInitData kbData;
|
||||
kbData.title = app.GetString(IDS_CREATE_NEW_WORLD_SEED);
|
||||
kbData.defaultText = m_editSeed.getLabel();
|
||||
kbData.maxChars = 60;
|
||||
kbData.callback = &UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback;
|
||||
kbData.lpParam = this;
|
||||
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData);
|
||||
}
|
||||
#else
|
||||
m_bIgnoreInput=true;
|
||||
#ifdef __PS3__
|
||||
int language = XGetLanguage();
|
||||
|
|
@ -583,12 +627,12 @@ void UIScene_LaunchMoreOptionsMenu::handlePress(F64 controlId, F64 childId)
|
|||
InputManager.RequestKeyboard(app.GetString(IDS_CREATE_NEW_WORLD_SEED),m_editSeed.getLabel(),(DWORD)0,60,&UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
break;
|
||||
default:
|
||||
// 4J Stu - Use a different keyboard for non-asian languages so we don't have prediction on
|
||||
InputManager.RequestKeyboard(app.GetString(IDS_CREATE_NEW_WORLD_SEED),m_editSeed.getLabel(),(DWORD)0,60,&UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback,this,C_4JInput::EKeyboardMode_Alphabet_Extended);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
InputManager.RequestKeyboard(app.GetString(IDS_CREATE_NEW_WORLD_SEED),m_editSeed.getLabel(),(DWORD)0,60,&UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback,this,C_4JInput::EKeyboardMode_Default);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ protected:
|
|||
public:
|
||||
virtual void tick();
|
||||
virtual void handleDestroy();
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
#endif
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
virtual void handleFocusChange(F64 controlId, F64 childId);
|
||||
|
|
@ -160,6 +164,8 @@ private:
|
|||
|
||||
#ifdef __PSVITA__
|
||||
virtual void handleTouchInput(unsigned int iPad, S32 x, S32 y, int iId, bool bPressed, bool bRepeat, bool bReleased);
|
||||
virtual UIControl* GetMainPanel();
|
||||
#endif //__PSVITA__
|
||||
#if defined(__PSVITA__) || defined(_WINDOWS64)
|
||||
virtual UIControl* GetMainPanel();
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1168,6 +1168,43 @@ void UIScene_LoadOrJoinMenu::handleInput(int iPad, int key, bool repeat, bool pr
|
|||
LaunchSaveTransfer();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef _WINDOWS64
|
||||
// Right click on a save opens save options (same as RB / ACTION_MENU_RIGHT_SCROLL)
|
||||
if(pressed && !repeat && ProfileManager.IsFullVersion() && !StorageManager.GetSaveDisabled())
|
||||
{
|
||||
if(DoesSavesListHaveFocus() && (m_iDefaultButtonsC > 0) && (m_iSaveListIndex >= m_iDefaultButtonsC))
|
||||
{
|
||||
m_bIgnoreInput = true;
|
||||
if(StorageManager.EnoughSpaceForAMinSaveGame())
|
||||
{
|
||||
UINT uiIDA[3];
|
||||
uiIDA[0]=IDS_CONFIRM_CANCEL;
|
||||
uiIDA[1]=IDS_TITLE_RENAMESAVE;
|
||||
uiIDA[2]=IDS_TOOLTIPS_DELETESAVE;
|
||||
ui.RequestAlertMessage(IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS, uiIDA, 3, iPad,&UIScene_LoadOrJoinMenu::SaveOptionsDialogReturned,this);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT uiIDA[2];
|
||||
uiIDA[0]=IDS_CONFIRM_CANCEL;
|
||||
uiIDA[1]=IDS_CONFIRM_OK;
|
||||
ui.RequestAlertMessage(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, iPad,&UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned,this);
|
||||
}
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
else if(DoesMashUpWorldHaveFocus() && (m_iSaveListIndex != JOIN_LOAD_CREATE_BUTTON_INDEX))
|
||||
{
|
||||
LevelGenerationOptions *levelGen = m_generators.at(m_iSaveListIndex - 1);
|
||||
if(!levelGen->isTutorial() && levelGen->requiresTexturePack())
|
||||
{
|
||||
m_bIgnoreInput = true;
|
||||
app.HideMashupPackWorld(m_iPad, levelGen->getRequiredTexturePackId());
|
||||
m_iState = e_SavesRepopulateAfterMashupHide;
|
||||
}
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ACTION_MENU_Y:
|
||||
|
|
@ -2394,7 +2431,7 @@ int UIScene_LoadOrJoinMenu::SaveOptionsDialogReturned(void *pParam,int iPad,C4JS
|
|||
kbData.maxChars = 25;
|
||||
kbData.callback = &UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback;
|
||||
kbData.lpParam = pClass;
|
||||
kbData.pcMode = !Win64_IsControllerConnected();
|
||||
kbData.pcMode = g_KBMInput.IsKBMActive();
|
||||
ui.NavigateToScene(pClass->m_iPad, eUIScene_Keyboard, &kbData);
|
||||
}
|
||||
#elif defined _DURANGO
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ UIScene_SignEntryMenu::UIScene_SignEntryMenu(int iPad, void *_initData, UILayer
|
|||
|
||||
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;
|
||||
|
|
@ -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,31 +215,124 @@ 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;
|
||||
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((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)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (isDirectEditBlocking()) return;
|
||||
#endif
|
||||
switch((int)controlId)
|
||||
{
|
||||
case eControl_Confirm:
|
||||
|
|
@ -170,6 +346,28 @@ void UIScene_SignEntryMenu::handlePress(F64 controlId, F64 childId)
|
|||
case eControl_Line4:
|
||||
{
|
||||
m_iEditingLine = (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.
|
||||
|
|
@ -187,6 +385,7 @@ void UIScene_SignEntryMenu::handlePress(F64 controlId, F64 childId)
|
|||
}
|
||||
#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);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ private:
|
|||
int m_iEditingLine;
|
||||
bool m_bConfirmed;
|
||||
bool m_bIgnoreInput;
|
||||
int m_iSignCursorFrame;
|
||||
#ifdef _WINDOWS64
|
||||
int m_iActiveDirectEditLine;
|
||||
bool m_bNeedsInitialEdit;
|
||||
bool m_bSkipTickNav;
|
||||
#endif
|
||||
|
||||
UIControl_Button m_buttonConfirm;
|
||||
UIControl_Label m_labelMessage;
|
||||
|
|
@ -50,6 +56,11 @@ protected:
|
|||
public:
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
#ifdef _WINDOWS64
|
||||
virtual void getDirectEditInputs(vector<UIControl_TextInput*> &inputs);
|
||||
virtual void onDirectEditFinished(UIControl_TextInput *input, UIControl_TextInput::EDirectEditResult result);
|
||||
virtual bool handleMouseClick(F32 x, F32 y);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void handlePress(F64 controlId, F64 childId);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,44 @@ void Font::renderStyleLine(float x0, float y0, float x1, float y1)
|
|||
t->end();
|
||||
}
|
||||
|
||||
void Font::addCharacterQuad(wchar_t c)
|
||||
{
|
||||
float xOff = c % m_cols * m_charWidth;
|
||||
float yOff = c / m_cols * m_charWidth;
|
||||
float width = charWidths[c] - .01f;
|
||||
float height = m_charHeight - .01f;
|
||||
float fontWidth = m_cols * m_charWidth;
|
||||
float fontHeight = m_rows * m_charHeight;
|
||||
const float shear = m_italic ? (height * 0.25f) : 0.0f;
|
||||
float x0 = xPos, x1 = xPos + width + shear;
|
||||
float y0 = yPos, y1 = yPos + height;
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x0, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x1, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x1, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x0, y0, 0.0f);
|
||||
|
||||
if (m_bold)
|
||||
{
|
||||
float dx = 1.0f;
|
||||
t->tex(xOff / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x0 + dx, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, (yOff + 7.99f) / fontHeight);
|
||||
t->vertex(x1 + dx, y1, 0.0f);
|
||||
t->tex((xOff + width) / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x1 + dx, y0, 0.0f);
|
||||
t->tex(xOff / fontWidth, yOff / fontHeight);
|
||||
t->vertex(x0 + dx, y0, 0.0f);
|
||||
}
|
||||
|
||||
xPos += static_cast<float>(charWidths[c]);
|
||||
}
|
||||
|
||||
void Font::renderCharacter(wchar_t c)
|
||||
{
|
||||
float xOff = c % m_cols * m_charWidth;
|
||||
|
|
@ -255,11 +293,13 @@ void Font::draw(const wstring &str, bool dropShadow)
|
|||
{
|
||||
// Bind the texture
|
||||
textures->bindTexture(m_textureLocation);
|
||||
|
||||
bool noise = false;
|
||||
m_bold = m_italic = m_underline = m_strikethrough = false;
|
||||
wstring cleanStr = sanitize(str);
|
||||
|
||||
Tesselator *t = Tesselator::getInstance();
|
||||
t->begin();
|
||||
|
||||
for (int i = 0; i < static_cast<int>(cleanStr.length()); ++i)
|
||||
{
|
||||
// Map character
|
||||
|
|
@ -270,8 +310,10 @@ void Font::draw(const wstring &str, bool dropShadow)
|
|||
wchar_t ca = cleanStr[i+1];
|
||||
if (!isSectionFormatCode(ca))
|
||||
{
|
||||
t->end();
|
||||
renderCharacter(167);
|
||||
renderCharacter(ca);
|
||||
t->begin();
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -294,14 +336,10 @@ void Font::draw(const wstring &str, bool dropShadow)
|
|||
{
|
||||
noise = false;
|
||||
if (colorN < 0 || colorN > 15) colorN = 15;
|
||||
|
||||
if (dropShadow) colorN += 16;
|
||||
|
||||
int color = colors[colorN];
|
||||
glColor3f((color >> 16) / 255.0F, ((color >> 8) & 255) / 255.0F, (color & 255) / 255.0F);
|
||||
}
|
||||
|
||||
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -317,8 +355,10 @@ void Font::draw(const wstring &str, bool dropShadow)
|
|||
c = newc;
|
||||
}
|
||||
|
||||
renderCharacter(c);
|
||||
addCharacterQuad(c);
|
||||
}
|
||||
|
||||
t->end();
|
||||
}
|
||||
|
||||
void Font::draw(const wstring& str, int x, int y, int color, bool dropShadow)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
private:
|
||||
void renderCharacter(wchar_t c); // 4J added
|
||||
void addCharacterQuad(wchar_t c);
|
||||
void renderStyleLine(float x0, float y0, float x1, float y1); // solid line for underline/strikethrough
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -971,7 +971,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
#if defined(_WINDOWS64)
|
||||
#if 0 // defined(_WINDOWS64) // Temporarily disable this chat in favor of iggy chat until we have better visual parity
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, static_cast<float>(screenHeight - iSafezoneYHalf - iTooltipsYOffset - 16 - 3 + 22) - 24.0f, 0.0f);
|
||||
|
||||
|
|
|
|||
|
|
@ -1499,7 +1499,7 @@ void Minecraft::run_middle()
|
|||
}
|
||||
|
||||
// Utility keys always work regardless of KBM active state
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE) && !ui.IsTutorialVisible(i) && !ui.GetMenuDisplayed(i))
|
||||
if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE) && !ui.GetMenuDisplayed(i))
|
||||
{
|
||||
localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_PAUSEMENU;
|
||||
app.DebugPrintf("PAUSE PRESSED (keyboard) - ipad = %d\n",i);
|
||||
|
|
@ -1522,7 +1522,7 @@ void Minecraft::run_middle()
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef _FINAL_BUILD
|
||||
#if _DEBUG // ndef _FINAL_BUILD // Disable conflicting debug functionality in release builds
|
||||
if( app.DebugSettingsOn() && app.GetUseDPadForDebug() )
|
||||
{
|
||||
localplayers[i]->ullDpad_last = 0;
|
||||
|
|
@ -3651,7 +3651,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
|
||||
if (player->missTime > 0) player->missTime--;
|
||||
|
||||
#ifdef _DEBUG_MENUS_ENABLED
|
||||
#ifdef _DEBUG//_MENUS_ENABLED // disable DPad cheats on release builds
|
||||
if(app.DebugSettingsOn())
|
||||
{
|
||||
#ifndef __PSVITA__
|
||||
|
|
|
|||
|
|
@ -126,40 +126,16 @@ void KeyboardMouseInput::Tick()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
if (!IsGameInFront())
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
while (ShowCursor(TRUE) < 0) {}
|
||||
}
|
||||
else if (m_cursorHiddenForUI)
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
else if (m_mouseGrabbed && g_hWnd)
|
||||
{
|
||||
ClipCursorToWindow(g_hWnd);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
center.x = (rc.right - rc.left) / 2;
|
||||
center.y = (rc.bottom - rc.top) / 2;
|
||||
ClientToScreen(g_hWnd, ¢er);
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
#else
|
||||
if ((m_mouseGrabbed || m_cursorHiddenForUI) && g_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
center.x = (rc.right - rc.left) / 2;
|
||||
center.y = (rc.bottom - rc.top) / 2;
|
||||
ClientToScreen(g_hWnd, ¢er);
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
#endif
|
||||
if ((m_mouseGrabbed || m_cursorHiddenForUI) && m_windowFocused && g_hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
center.x = (rc.right - rc.left) / 2;
|
||||
center.y = (rc.bottom - rc.top) / 2;
|
||||
ClientToScreen(g_hWnd, ¢er);
|
||||
SetCursorPos(center.x, center.y);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseInput::OnKeyDown(int vkCode)
|
||||
|
|
|
|||
|
|
@ -604,7 +604,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
else if (vk == VK_MENU)
|
||||
vk = (lParam & (1 << 24)) ? VK_RMENU : VK_LMENU;
|
||||
g_KBMInput.OnKeyDown(vk);
|
||||
break;
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
|
|
|
|||
|
|
@ -463,6 +463,23 @@ BOOL ConsoleSaveFileOriginal::closeHandle( FileEntry *file )
|
|||
void ConsoleSaveFileOriginal::finalizeWrite()
|
||||
{
|
||||
LockSaveAccess();
|
||||
|
||||
// Ensure buffer is large enough for the full file including header table.
|
||||
// New file entries (e.g. from RegionFile creation) increase GetFileSize()
|
||||
// without triggering MoveDataBeyond, so the committed pages may be short.
|
||||
DWORD currentHeapSize = pagesCommitted * CSF_PAGE_SIZE;
|
||||
DWORD desiredSize = header.GetFileSize();
|
||||
if( desiredSize > currentHeapSize )
|
||||
{
|
||||
unsigned int pagesRequired = ( desiredSize + (CSF_PAGE_SIZE - 1 ) ) / CSF_PAGE_SIZE;
|
||||
void *pvRet = VirtualAlloc(pvHeap, pagesRequired * CSF_PAGE_SIZE, COMMIT_ALLOCATION, PAGE_READWRITE);
|
||||
if( pvRet == NULL )
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
pagesCommitted = pagesRequired;
|
||||
}
|
||||
|
||||
header.WriteHeader( pvSaveMem );
|
||||
ReleaseSaveAccess();
|
||||
}
|
||||
|
|
|
|||
40
README.md
40
README.md
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
This project contains the source code of Minecraft Legacy Console Edition v1.6.0560.0 (TU19) from https://archive.org/details/minecraft-legacy-console-edition-source-code, with some fixes and improvements applied.
|
||||
|
||||
[Nightly Build](https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly)
|
||||
## Download
|
||||
Windows users can download our [Nightly Build](https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly)! Simply download the `.zip` file and extract it to a folder where you'd like to keep the game. You can set your username in `username.txt` (you'll have to make this file) and add servers to connect to in `servers.txt`
|
||||
|
||||
## Platform Support
|
||||
|
||||
|
|
@ -34,30 +35,42 @@ Basic LAN multiplayer is available on the Windows build
|
|||
- Other players on the same LAN can discover the session from the in-game Join Game menu
|
||||
- Game connections use TCP port `25565` by default
|
||||
- LAN discovery uses UDP port `25566`
|
||||
- Add servers to your server list with `servers.txt` (temp solution)
|
||||
- Rename yourself without losing data by keeping your `uid.dat`
|
||||
|
||||
This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||
Parts of this feature are based on code from [LCEMP](https://github.com/LCEMP/LCEMP) (thanks!)
|
||||
|
||||
### servers.txt
|
||||
|
||||
To add a server to your game, create the `servers.txt` file in the same directory as you have `Minecraft.Client.exe`. Inside, follow this format:
|
||||
```
|
||||
serverip.example.com
|
||||
25565
|
||||
The name of your server in UI!
|
||||
```
|
||||
|
||||
For example, here's a valid servers.txt
|
||||
```
|
||||
1.1.1.1
|
||||
25565
|
||||
Cloudflare's Very Own LCE Server
|
||||
127.0.0.1
|
||||
25565
|
||||
Localhost Test Crap
|
||||
```
|
||||
|
||||
### Launch Arguments
|
||||
|
||||
| Argument | Description |
|
||||
|--------------------|-----------------------------------------------------------------------------------------------------|
|
||||
| `-name <username>` | Sets your in-game username. |
|
||||
| `-server` | Launches a headless server instead of the client. |
|
||||
| `-ip <address>` | Client mode: manually connect to an IP. Server mode: override the bind IP from `server.properties`. |
|
||||
| `-port <port>` | Client mode: override the join port. Server mode: override the listen port from `server.properties`.|
|
||||
| `-fullscreen` | Launches the game in Fullscreen mode |
|
||||
|
||||
Example:
|
||||
```
|
||||
Minecraft.Client.exe -name Steve -ip 192.168.0.25 -port 25565
|
||||
Minecraft.Client.exe -name Steve -fullscreen
|
||||
```
|
||||
|
||||
Headless server example:
|
||||
```
|
||||
Minecraft.Client.exe -server -ip 0.0.0.0 -port 25565
|
||||
```
|
||||
|
||||
The headless server also reads and writes `server.properties` in the working directory. If `-ip` / `-port` are omitted in `-server` mode, it falls back to `server-ip` / `server-port` from that file. Dedicated-server host options such as `trust-players`, `pvp`, `fire-spreads`, `tnt`, `difficulty`, `gamemode`, `spawn-animals`, and `spawn-npcs` are persisted there as well.
|
||||
|
||||
## Controls (Keyboard & Mouse)
|
||||
|
||||
- **Movement**: `W` `A` `S` `D`
|
||||
|
|
@ -65,6 +78,7 @@ The headless server also reads and writes `server.properties` in the working dir
|
|||
- **Sneak / Fly (Down)**: `Shift` (Hold)
|
||||
- **Sprint**: `Ctrl` (Hold) or Double-tap `W`
|
||||
- **Inventory**: `E`
|
||||
- **Chat**: `T`
|
||||
- **Drop Item**: `Q`
|
||||
- **Crafting**: `C` Use `Q` and `E` to move through tabs (cycles Left/Right)
|
||||
- **Toggle View (FPS/TPS)**: `F5`
|
||||
|
|
|
|||
Loading…
Reference in a new issue