mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-23 20:09:46 +03:00
migrate ALMOST everything from source tree into client
This commit is contained in:
39
source/client/gui/components/AvailableGamesList.cpp
Normal file
39
source/client/gui/components/AvailableGamesList.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "AvailableGamesList.hpp"
|
||||
|
||||
AvailableGamesList::AvailableGamesList(Minecraft* a, int b, int c, int d, int e, int f) :
|
||||
ScrolledSelectionList(a, b, c, d, e, f)
|
||||
{
|
||||
}
|
||||
|
||||
int AvailableGamesList::getNumberOfItems()
|
||||
{
|
||||
return int(m_games.size());
|
||||
}
|
||||
|
||||
bool AvailableGamesList::isSelectedItem(int i)
|
||||
{
|
||||
return m_selectedIndex == i;
|
||||
}
|
||||
|
||||
void AvailableGamesList::renderBackground()
|
||||
{
|
||||
}
|
||||
|
||||
void AvailableGamesList::renderItem(int idx, int x, int y, int width, Tesselator& t)
|
||||
{
|
||||
drawString(m_pMinecraft->m_pFont, std::string(m_games[idx].m_name.C_String()), x, y + 2, 0xFFFFA0);
|
||||
drawString(m_pMinecraft->m_pFont, std::string(m_games[idx].m_address.ToString()), x, y + 16, 0xFFFFA0);
|
||||
}
|
||||
|
||||
void AvailableGamesList::selectItem(int index, bool b)
|
||||
{
|
||||
m_selectedIndex = index;
|
||||
}
|
||||
28
source/client/gui/components/AvailableGamesList.hpp
Normal file
28
source/client/gui/components/AvailableGamesList.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ScrolledSelectionList.hpp"
|
||||
#include "PingedCompatibleServer.hpp"
|
||||
|
||||
class AvailableGamesList : public ScrolledSelectionList
|
||||
{
|
||||
public:
|
||||
AvailableGamesList(Minecraft*, int, int, int, int, int);
|
||||
int getNumberOfItems() override;
|
||||
bool isSelectedItem(int i) override;
|
||||
void renderBackground() override;
|
||||
void renderItem(int, int, int, int, Tesselator& t) override;
|
||||
void selectItem(int, bool) override;
|
||||
|
||||
public:
|
||||
int m_selectedIndex;
|
||||
std::vector<PingedCompatibleServer> m_games;
|
||||
};
|
||||
|
||||
97
source/client/gui/components/Button.cpp
Normal file
97
source/client/gui/components/Button.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "Button.hpp"
|
||||
|
||||
Button::Button(int a2, int xPos, int yPos, int btnWidth, int btnHeight, const std::string& text)
|
||||
{
|
||||
field_30 = a2;
|
||||
m_xPos = xPos;
|
||||
m_yPos = yPos;
|
||||
field_18 = text;
|
||||
m_width = btnWidth;
|
||||
m_height = btnHeight;
|
||||
}
|
||||
|
||||
Button::Button(int a2, int xPos, int yPos, const std::string& text)
|
||||
{
|
||||
field_30 = a2;
|
||||
m_xPos = xPos;
|
||||
m_yPos = yPos;
|
||||
field_18 = text;
|
||||
m_width = 200;
|
||||
m_height = 24;
|
||||
}
|
||||
|
||||
Button::Button(int a2, const std::string& text)
|
||||
{
|
||||
field_30 = a2;
|
||||
field_18 = text;
|
||||
m_width = 200;
|
||||
m_height = 24;
|
||||
}
|
||||
|
||||
bool Button::clicked(Minecraft* pMinecraft, int xPos, int yPos)
|
||||
{
|
||||
if (!m_bEnabled) return false;
|
||||
if (xPos < m_xPos) return false;
|
||||
if (yPos < m_yPos) return false;
|
||||
if (xPos >= m_xPos + m_width) return false;
|
||||
if (yPos >= m_yPos + m_height) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Button::getYImage(bool bHovered)
|
||||
{
|
||||
if (!m_bEnabled) return 0;
|
||||
if (bHovered) return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Button::released(int xPos, int yPos)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Button::renderBg(Minecraft*, int, int)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Button::render(Minecraft* pMinecraft, int xPos, int yPos)
|
||||
{
|
||||
if (!m_bVisible) return;
|
||||
|
||||
#ifdef ENH_HIGHLIGHT_BY_HOVER
|
||||
field_36 = clicked(pMinecraft, xPos, yPos);
|
||||
#endif
|
||||
|
||||
Font* pFont = pMinecraft->m_pFont;
|
||||
Textures* pTexs = pMinecraft->m_pTextures;
|
||||
|
||||
pTexs->loadAndBindTexture("gui/gui.png");
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
int iYPos = 20 * getYImage(field_36) + 46;
|
||||
|
||||
blit(m_xPos, m_yPos, 0, iYPos, m_width / 2, m_height, 0, 20);
|
||||
blit(m_xPos + m_width / 2, m_yPos, 200 - m_width / 2, iYPos, m_width / 2, m_height, 0, 20);
|
||||
|
||||
renderBg(pMinecraft, xPos, yPos);
|
||||
|
||||
int textColor;
|
||||
if (!m_bEnabled)
|
||||
textColor = int(0xFFA0A0A0U);
|
||||
else if (field_36)
|
||||
textColor = int(0xFFFFA0U);
|
||||
else
|
||||
textColor = int(0xE0E0E0U);
|
||||
|
||||
drawCenteredString(pFont, field_18, m_xPos + m_width / 2, m_yPos + (m_height - 8) / 2, textColor);
|
||||
}
|
||||
46
source/client/gui/components/Button.hpp
Normal file
46
source/client/gui/components/Button.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
|
||||
class Screen;
|
||||
|
||||
class Button : public GuiComponent
|
||||
{
|
||||
public:
|
||||
Button(int, int x, int y, int width, int height, const std::string&);
|
||||
Button(int, int x, int y, const std::string&);
|
||||
Button(int, const std::string&);
|
||||
|
||||
// I can't possibly explain why Minecraft is referenced here
|
||||
bool clicked(Minecraft*, int xPos, int yPos);
|
||||
int getYImage(bool bHovered);
|
||||
void released(int xPos, int yPos);
|
||||
void renderBg(Minecraft*, int, int);
|
||||
void render(Minecraft*, int xPos, int yPos);
|
||||
|
||||
public:
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
int m_xPos = 0;
|
||||
int m_yPos = 0;
|
||||
std::string field_18 = "";
|
||||
int field_30;
|
||||
bool m_bEnabled = true;
|
||||
bool m_bVisible = true;
|
||||
bool field_36 = false;
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
int m_lastX = 0;
|
||||
int m_lastY = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
327
source/client/gui/components/RolledSelectionList.cpp
Normal file
327
source/client/gui/components/RolledSelectionList.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "RolledSelectionList.hpp"
|
||||
|
||||
static float g_RolledSelectionListUnk, g_RolledSelectionListUnk2;
|
||||
|
||||
RolledSelectionList::RolledSelectionList(Minecraft* minecraft, int a, int b, int c, int d, int e, int f, int g)
|
||||
{
|
||||
m_pMinecraft = minecraft;
|
||||
m_itemWidth = g;
|
||||
field_18 = a;
|
||||
field_C = float(c);
|
||||
field_10 = float(d);
|
||||
field_1C = b;
|
||||
field_20 = float(e);
|
||||
field_24 = float(f);
|
||||
g_RolledSelectionListUnk = field_30 = field_34 = float(g - a) / 2.0f;
|
||||
}
|
||||
|
||||
int RolledSelectionList::getItemAtXPositionRaw(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
return -1;
|
||||
|
||||
// @NOTE: redundant check
|
||||
int idx = x / m_itemWidth;
|
||||
if (idx < 0)
|
||||
return -1;
|
||||
|
||||
if (idx >= getNumberOfItems())
|
||||
return -1;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int RolledSelectionList::getItemAtPosition(int x, int y)
|
||||
{
|
||||
if (float(y) < field_20)
|
||||
return -1;
|
||||
if (float(y) > field_24)
|
||||
return -1;
|
||||
|
||||
return getItemAtXPositionRaw(transformX(x));
|
||||
}
|
||||
|
||||
bool RolledSelectionList::capXPosition()
|
||||
{
|
||||
float f1 = float(m_itemWidth - field_18) / 2.0f;
|
||||
int i1 = getNumberOfItems();
|
||||
|
||||
if (field_30 < f1)
|
||||
{
|
||||
field_30 = f1;
|
||||
field_38 = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
f1 += float(m_itemWidth * (i1 - 1));
|
||||
if (field_30 > f1)
|
||||
{
|
||||
field_30 = f1;
|
||||
field_38 = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RolledSelectionList::tick()
|
||||
{
|
||||
float diff = g_RolledSelectionListUnk - field_34;
|
||||
g_RolledSelectionListUnk = field_34;
|
||||
g_RolledSelectionListUnk2 = diff;
|
||||
field_34 = field_30 - field_38;
|
||||
}
|
||||
|
||||
void RolledSelectionList::render(int mouseX, int mouseY, float f)
|
||||
{
|
||||
renderBackground();
|
||||
|
||||
int nItems = getNumberOfItems();
|
||||
|
||||
// @TODO: fix gotos.
|
||||
if (!Mouse::_buttonStates[1])
|
||||
{
|
||||
if (field_28 < 0)
|
||||
{
|
||||
_crap:
|
||||
field_28 = -1;
|
||||
field_30 = getPos(f);
|
||||
goto _done;
|
||||
}
|
||||
|
||||
if (g_RolledSelectionListUnk2 < 0.0f)
|
||||
field_38 = Mth::Max(-20.0f, g_RolledSelectionListUnk2);
|
||||
else
|
||||
field_38 = Mth::Min(20.0f, g_RolledSelectionListUnk2);
|
||||
|
||||
if (fabsf(field_38) < 2.0f)
|
||||
{
|
||||
field_38 = 0.0f;
|
||||
|
||||
_continue:
|
||||
if (getTimeMs() - field_4C < 300)
|
||||
{
|
||||
int idx = transformX(mouseX) / m_itemWidth;
|
||||
if (idx >= 0)
|
||||
{
|
||||
if (field_50 == idx && abs(field_3C - mouseX) <= 9)
|
||||
selectItem(field_50, 0);
|
||||
}
|
||||
goto _crap;
|
||||
}
|
||||
goto _crap;
|
||||
}
|
||||
|
||||
if (fabsf(field_38) > 10.0f)
|
||||
{
|
||||
goto _crap;
|
||||
}
|
||||
|
||||
goto _continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
touched();
|
||||
|
||||
if (float(mouseY) >= field_20 && float(mouseY) <= field_24)
|
||||
{
|
||||
if (field_28 == -1)
|
||||
{
|
||||
field_4C = getTimeMs();
|
||||
field_3C = mouseX;
|
||||
field_50 = getItemAtPosition(mouseX, field_1C / 2);
|
||||
}
|
||||
else if (field_28 >= 0)
|
||||
{
|
||||
field_34 = field_30 = field_30 - (float(mouseX) - field_2C);
|
||||
}
|
||||
|
||||
field_28 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_done:
|
||||
field_2C = float(mouseX);
|
||||
|
||||
capXPosition();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_FOG);
|
||||
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
t.color(0x202020);
|
||||
t.vertexUV(field_C, field_24, 0.0f, (field_C + float(int(field_30))) / 32.0f, field_24 / 32.0f);
|
||||
t.vertexUV(field_10, field_24, 0.0f, (field_10 + float(int(field_30))) / 32.0f, field_24 / 32.0f);
|
||||
t.vertexUV(field_10, field_20, 0.0f, (field_10 + float(int(field_30))) / 32.0f, field_20 / 32.0f);
|
||||
t.vertexUV(field_C, field_20, 0.0f, (field_C + float(int(field_30))) / 32.0f, field_20 / 32.0f);
|
||||
t.draw();
|
||||
|
||||
if (!getNumberOfItems())
|
||||
field_30 = 0.0f;
|
||||
|
||||
if (field_48)
|
||||
renderHeader(int(field_C + 4.0f - float(int(field_30))), field_1C / 2 - 40, t);
|
||||
|
||||
for (int i = 0; i < nItems; i++)
|
||||
{
|
||||
float itemX = float(field_44 + float(int(field_C + 4.0f - float(field_30))) + m_itemWidth * i);
|
||||
if (field_10 < itemX) continue;
|
||||
|
||||
float width = m_itemWidth - 4.0f;
|
||||
if (itemX + width < field_C) continue;
|
||||
|
||||
if (m_bRenderSelection && isSelectedItem(i))
|
||||
{
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
t.begin();
|
||||
t.color(m_bComponentSelected ? 0x7F89BF : 0x808080);
|
||||
|
||||
float right = itemX + width;
|
||||
float up = float(field_1C) / 2.0f - 48.0f - 4.0f;
|
||||
float dn = float(field_1C) / 2.0f + 48.0f - 4.0f;
|
||||
|
||||
t.vertexUV(itemX - 2, up, 0.0f, 0.0f, 0.0f);
|
||||
t.vertexUV(itemX - 2, dn, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(right + 2, dn, 0.0f, 1.0f, 1.0f);
|
||||
t.vertexUV(right + 2, up, 0.0f, 0.0f, 1.0f);
|
||||
t.color(0x000000);
|
||||
t.vertexUV(itemX - 1, up + 1.0f, 0.0f, 0.0f, 0.0f);
|
||||
t.vertexUV(itemX - 1, dn - 1.0f, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(right + 1, dn - 1.0f, 0.0f, 1.0f, 1.0f);
|
||||
t.vertexUV(right + 1, up + 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
t.draw();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
renderItem(i, int(itemX), field_1C / 2 - 40, int(width), t);
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
renderHoleBackground(0.0f, field_20, 255, 255);
|
||||
renderHoleBackground(field_24, float(field_1C), 255, 255);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// @BUG: The X and Y coordinates have been swapped. This causes the gradient to not render
|
||||
// in the right place.
|
||||
#ifdef ORIGINAL_CODE
|
||||
t.begin();
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_20, field_C + 4.0f, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_24, field_C + 4.0f, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_24, field_C, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_20, field_C, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
t.begin();
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_20, field_10, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_24, field_10, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_24, field_10 - 4.0f, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_20, field_10 - 4.0f, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
#else
|
||||
t.begin();
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_C + 4.0f, field_20, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_C + 4.0f, field_24, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_C, field_24, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_C, field_20, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
t.begin();
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_10, field_20, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_10, field_24, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_10 - 4.0f, field_24, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_10 - 4.0f, field_20, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
#endif
|
||||
|
||||
renderDecorations(mouseX, mouseY);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glShadeModel(GL_FLAT);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void RolledSelectionList::renderHoleBackground(float y1, float y2, int a, int b)
|
||||
{
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
t.color(0x505050, b);
|
||||
t.vertexUV(0.0f, y2, 0.0f, 0.0f, y2 / 32.0f);
|
||||
t.vertexUV(float(field_18), y2, 0.0f, float(field_18) / 32.0f, y2 / 32.0f);
|
||||
t.color(0x505050, a);
|
||||
t.vertexUV(float(field_18), y1, 0.0f, float(field_18) / 32.0f, y1 / 32.0f);
|
||||
t.vertexUV(0.0f, y1, 0.0f, 0.0f, y1 / 32.0f);
|
||||
t.draw();
|
||||
}
|
||||
|
||||
void RolledSelectionList::setRenderSelection(bool b)
|
||||
{
|
||||
m_bRenderSelection = b;
|
||||
}
|
||||
|
||||
void RolledSelectionList::setComponentSelected(bool b)
|
||||
{
|
||||
m_bComponentSelected = b;
|
||||
}
|
||||
|
||||
int RolledSelectionList::getMaxPosition()
|
||||
{
|
||||
return field_44 + m_itemWidth * getNumberOfItems();
|
||||
}
|
||||
|
||||
float RolledSelectionList::getPos(float f)
|
||||
{
|
||||
return field_34 - field_38 * f;
|
||||
}
|
||||
|
||||
void RolledSelectionList::touched()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RolledSelectionList::renderHeader(int a, int b, Tesselator& t)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RolledSelectionList::renderDecorations(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
void RolledSelectionList::clickedHeader(int x, int y)
|
||||
{
|
||||
|
||||
}
|
||||
67
source/client/gui/components/RolledSelectionList.hpp
Normal file
67
source/client/gui/components/RolledSelectionList.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
|
||||
class RolledSelectionList : public GuiComponent
|
||||
{
|
||||
public:
|
||||
RolledSelectionList(Minecraft*, int, int, int, int, int, int, int);
|
||||
virtual int getItemAtPosition(int, int);
|
||||
virtual bool capXPosition();
|
||||
virtual void tick();
|
||||
virtual void render(int mouseX, int mouseY, float);
|
||||
virtual void renderHoleBackground(float y1, float y2, int a, int b);
|
||||
virtual void setRenderSelection(bool);
|
||||
virtual void setComponentSelected(bool);
|
||||
virtual int getNumberOfItems() = 0;
|
||||
virtual void selectItem(int, bool) = 0;
|
||||
virtual bool isSelectedItem(int) = 0;
|
||||
virtual int getMaxPosition();
|
||||
virtual float getPos(float f);
|
||||
virtual void touched();
|
||||
virtual void renderItem(int, int, int, int, Tesselator&) = 0;
|
||||
virtual void renderHeader(int, int, Tesselator&);
|
||||
virtual void renderBackground() = 0;
|
||||
virtual void renderDecorations(int x, int y);
|
||||
virtual void clickedHeader(int, int);
|
||||
|
||||
int getItemAtXPositionRaw(int x);
|
||||
|
||||
// @NOTE: This is inlined.
|
||||
inline int transformX(int x)
|
||||
{
|
||||
return int(x - field_C - float(field_44) + float(int(field_30)) - 4.0f);
|
||||
}
|
||||
|
||||
public:
|
||||
Minecraft* m_pMinecraft;
|
||||
float field_C;
|
||||
float field_10;
|
||||
int m_itemWidth;
|
||||
int field_18;
|
||||
int field_1C;
|
||||
float field_20;
|
||||
float field_24;
|
||||
int field_28 = -2;
|
||||
float field_2C = 0.0f;
|
||||
float field_30;
|
||||
float field_34;
|
||||
float field_38 = 0.0f;
|
||||
int field_3C = -1;
|
||||
bool m_bRenderSelection = true;
|
||||
bool m_bComponentSelected = false;
|
||||
int field_44 = 0;
|
||||
bool field_48 = false;
|
||||
int field_4C = 0;
|
||||
int field_50 = -1;
|
||||
};
|
||||
|
||||
241
source/client/gui/components/ScrolledSelectionList.cpp
Normal file
241
source/client/gui/components/ScrolledSelectionList.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "ScrolledSelectionList.hpp"
|
||||
|
||||
#define C_ITEM_WIDTH (220)
|
||||
|
||||
ScrolledSelectionList::ScrolledSelectionList(Minecraft* minecraft, int a3, int a4, int a5, int a6, int a7) :
|
||||
m_pMinecraft(minecraft),
|
||||
field_C(float(a5)),
|
||||
field_10(float(a6)),
|
||||
m_itemHeight(a7),
|
||||
field_18(a3),
|
||||
field_1C(a4),
|
||||
field_20(float(a3))
|
||||
{
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::setRenderSelection(bool b)
|
||||
{
|
||||
m_bRenderSelection = b;
|
||||
}
|
||||
|
||||
int ScrolledSelectionList::getMaxPosition()
|
||||
{
|
||||
return field_48 + m_itemHeight * getNumberOfItems();
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::renderHeader(int a, int b, Tesselator& t)
|
||||
{
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::renderDecorations(int a, int b)
|
||||
{
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::clickedHeader(int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
int ScrolledSelectionList::getItemAtPosition(int x, int y)
|
||||
{
|
||||
if (x < field_18 / 2 - C_ITEM_WIDTH / 2)
|
||||
return -1;
|
||||
|
||||
if (x > field_18 / 2 + C_ITEM_WIDTH / 2)
|
||||
return -1;
|
||||
|
||||
return getItemAtYPositionRaw(transformY(y));
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::capYPosition()
|
||||
{
|
||||
float maxY = float(getMaxPosition()) - (float(field_10 - field_C) - 4.0f);
|
||||
if (maxY < 0.0f)
|
||||
maxY *= 0.5f;
|
||||
|
||||
if (field_34 < 0.0f)
|
||||
field_34 = 0.0f;
|
||||
if (field_34 > maxY)
|
||||
field_34 = maxY;
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
|
||||
{
|
||||
renderBackground();
|
||||
|
||||
int nItems = getNumberOfItems();
|
||||
if (Mouse::_buttonStates[1])
|
||||
{
|
||||
if (float(mouseY) >= field_C && float(mouseY) <= field_10 && mouseY != field_28)
|
||||
{
|
||||
int field_2C_old = field_2C;
|
||||
|
||||
if (field_2C == -1)
|
||||
{
|
||||
field_2C = 1;
|
||||
}
|
||||
else if (field_2C == 1)
|
||||
{
|
||||
field_3C = mouseY;
|
||||
field_40 = getTimeMs();
|
||||
}
|
||||
else if (field_2C == 0)
|
||||
{
|
||||
float diff = float(mouseY) - field_30;
|
||||
field_34 -= diff;
|
||||
field_38 += diff;
|
||||
}
|
||||
|
||||
if (field_2C_old >= 0)
|
||||
field_2C = 0;
|
||||
|
||||
field_28 = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (field_2C >= 0)
|
||||
{
|
||||
if (fabsf(field_38) < 2.0f)
|
||||
field_38 = 0.0f;
|
||||
|
||||
if (getTimeMs() - field_40 < 300)
|
||||
{
|
||||
if (transformY(mouseY) / m_itemHeight >= 0 && m_itemHeight > abs(field_3C - mouseY))
|
||||
{
|
||||
selectItem(transformY(mouseY) / m_itemHeight, false);
|
||||
field_38 = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field_2C = -1;
|
||||
field_34 -= field_38;
|
||||
}
|
||||
|
||||
field_30 = float(mouseY);
|
||||
field_38 *= 0.75f;
|
||||
capYPosition();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_FOG);
|
||||
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
t.color(0x202020);
|
||||
t.vertexUV(field_24, field_10, 0.0f, field_24 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
|
||||
t.vertexUV(field_20, field_10, 0.0f, field_20 / 32.0f, (field_10 + float(int(field_34))) / 32.0f);
|
||||
t.vertexUV(field_20, field_C, 0.0f, field_20 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
|
||||
t.vertexUV(field_24, field_C, 0.0f, field_24 / 32.0f, (field_C + float(int(field_34))) / 32.0f);
|
||||
t.draw();
|
||||
|
||||
int itemX = field_18 / 2 - (C_ITEM_WIDTH - 4) / 2;
|
||||
int scrollY = int(field_C + 4 - float(int(field_34)));
|
||||
|
||||
if (field_45)
|
||||
renderHeader(itemX, scrollY, t);
|
||||
|
||||
for (int i = 0; i < nItems; i++)
|
||||
{
|
||||
float itemY = float(field_48 + scrollY + i * m_itemHeight);
|
||||
if (field_10 < itemY)
|
||||
continue;
|
||||
|
||||
float lowerY = itemY + m_itemHeight - 4;
|
||||
if (lowerY < field_C)
|
||||
continue;
|
||||
|
||||
if (m_bRenderSelection && isSelectedItem(i))
|
||||
{
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
t.begin();
|
||||
t.color(0x808080);
|
||||
t.vertexUV(float(field_18) / 2.0f - C_ITEM_WIDTH / 2.0f, lowerY + 2.0f, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f + C_ITEM_WIDTH / 2.0f, lowerY + 2.0f, 0.0f, 1.0f, 1.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f + C_ITEM_WIDTH / 2.0f, itemY - 2.0f, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f - C_ITEM_WIDTH / 2.0f, itemY - 2.0f, 0.0f, 0.0f, 0.0f);
|
||||
t.color(0x000000);
|
||||
t.vertexUV(float(field_18) / 2.0f - C_ITEM_WIDTH / 2.0f + 1, lowerY + 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f + C_ITEM_WIDTH / 2.0f - 1, lowerY + 1.0f, 0.0f, 1.0f, 1.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f + C_ITEM_WIDTH / 2.0f - 1, itemY - 1.0f, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(float(field_18) / 2.0f - C_ITEM_WIDTH / 2.0f + 1, itemY - 1.0f, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
renderItem(i, itemX, int(itemY), int(m_itemHeight - 4.0f), t);
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
renderHoleBackground(0.0f, field_C, 255, 255);
|
||||
renderHoleBackground(field_10, float(field_1C), 255, 255);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
t.begin();
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_24, field_C + 4.0f, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_20, field_C + 4.0f, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_20, field_C, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_24, field_C, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
t.begin();
|
||||
t.color(0, 255);
|
||||
t.vertexUV(field_24, field_10, 0.0f, 0.0f, 1.0f);
|
||||
t.vertexUV(field_20, field_10, 0.0f, 1.0f, 1.0f);
|
||||
t.color(0, 0);
|
||||
t.vertexUV(field_20, field_10 - 4.0f, 0.0f, 1.0f, 0.0f);
|
||||
t.vertexUV(field_24, field_10 - 4.0f, 0.0f, 0.0f, 0.0f);
|
||||
t.draw();
|
||||
|
||||
renderDecorations(mouseX, mouseY);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glShadeModel(GL_FLAT);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::renderHoleBackground(float a, float b, int c, int d)
|
||||
{
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png");
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
t.begin();
|
||||
t.color(0x505050, d);
|
||||
t.vertexUV(0.0f, b, 0.0f, 0.0f, b / 32.0f);
|
||||
t.vertexUV(float(field_18), b, 0.0f, field_18 / 32.0f, b / 32.0f);
|
||||
t.color(0x505050, c);
|
||||
t.vertexUV(float(field_18), a, 0.0f, field_18 / 32.0f, a / 32.0f);
|
||||
t.vertexUV(0.0f, a, 0.0f, 0.0f, a / 32.0f);
|
||||
t.draw();
|
||||
}
|
||||
|
||||
void ScrolledSelectionList::setRenderHeader(bool b, int i)
|
||||
{
|
||||
field_45 = b;
|
||||
if (!b)
|
||||
i = 0;
|
||||
field_48 = i;
|
||||
}
|
||||
79
source/client/gui/components/ScrolledSelectionList.hpp
Normal file
79
source/client/gui/components/ScrolledSelectionList.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GuiComponent.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
|
||||
class ScrolledSelectionList : public GuiComponent
|
||||
{
|
||||
public:
|
||||
ScrolledSelectionList(Minecraft*, int, int, int, int, int);
|
||||
|
||||
virtual void setRenderSelection(bool);
|
||||
virtual int getNumberOfItems() = 0;
|
||||
virtual void selectItem(int, bool) = 0;
|
||||
virtual bool isSelectedItem(int) = 0;
|
||||
virtual int getMaxPosition();
|
||||
virtual void renderItem(int, int, int, int, Tesselator&) = 0;
|
||||
virtual void renderHeader(int, int, Tesselator&);
|
||||
virtual void renderBackground() = 0;
|
||||
virtual void renderDecorations(int, int);
|
||||
virtual void clickedHeader(int x, int y);
|
||||
virtual int getItemAtPosition(int x, int y);
|
||||
virtual void capYPosition();
|
||||
virtual void render(int mouseX, int mouseY, float f);
|
||||
virtual void renderHoleBackground(float, float, int, int);
|
||||
|
||||
void setRenderHeader(bool, int);
|
||||
|
||||
|
||||
// @NOTE: This is inlined.
|
||||
inline int getItemAtYPositionRaw(int y)
|
||||
{
|
||||
if (y < 0)
|
||||
return -1;
|
||||
|
||||
// @NOTE: redundant check
|
||||
int idx = y / m_itemHeight;
|
||||
if (idx < 0)
|
||||
return -1;
|
||||
|
||||
if (idx >= getNumberOfItems())
|
||||
return -1;
|
||||
|
||||
return idx;
|
||||
}
|
||||
// @NOTE: This is also inlined.
|
||||
inline int transformY(int y)
|
||||
{
|
||||
return int(y - field_C - field_48 + field_34 - 4.0f);
|
||||
}
|
||||
|
||||
public:
|
||||
Minecraft* m_pMinecraft;
|
||||
float field_C;
|
||||
float field_10;
|
||||
int m_itemHeight;
|
||||
int field_18;
|
||||
int field_1C;
|
||||
float field_20;
|
||||
float field_24 = 0.0f;
|
||||
int field_28;
|
||||
int field_2C = -2;
|
||||
float field_30 = 0.0f;
|
||||
float field_34 = 0.0f;
|
||||
float field_38 = 0.0f;
|
||||
int field_3C = -1;
|
||||
int field_40 = 0;
|
||||
bool m_bRenderSelection = true;
|
||||
bool field_45 = false;
|
||||
int field_48 = 0;
|
||||
};
|
||||
|
||||
33
source/client/gui/components/SmallButton.cpp
Normal file
33
source/client/gui/components/SmallButton.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "SmallButton.hpp"
|
||||
|
||||
// @NOTE: Used in the ConfirmScreen.
|
||||
// I reckon this was used in the OptionsScreen as well, since the button sizes are the same.
|
||||
|
||||
SmallButton::SmallButton(int id, int x, int y, const std::string& str) :
|
||||
Button(id, x, y, 150, 20, str)
|
||||
{
|
||||
}
|
||||
|
||||
SmallButton::SmallButton(int id, int x, int y, int width, int height, const std::string& str) :
|
||||
Button(id, x, y, width, height, str)
|
||||
{
|
||||
}
|
||||
|
||||
SmallButton::SmallButton(int id, int x, int y, Options::Option* pOption, const std::string& str) :
|
||||
Button(id, x, y, 150, 20, str),
|
||||
m_pOption(pOption)
|
||||
{
|
||||
}
|
||||
|
||||
Options::Option* SmallButton::getOption()
|
||||
{
|
||||
return m_pOption;
|
||||
}
|
||||
24
source/client/gui/components/SmallButton.hpp
Normal file
24
source/client/gui/components/SmallButton.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Button.hpp"
|
||||
|
||||
class SmallButton : public Button
|
||||
{
|
||||
public:
|
||||
SmallButton(int id, int x, int y, const std::string& str);
|
||||
SmallButton(int id, int x, int y, int width, int height, const std::string& str);
|
||||
SmallButton(int id, int x, int y, Options::Option* pOption, const std::string& str);
|
||||
Options::Option* getOption();
|
||||
|
||||
private:
|
||||
Options::Option* m_pOption = nullptr;
|
||||
};
|
||||
|
||||
271
source/client/gui/components/TextInputBox.cpp
Normal file
271
source/client/gui/components/TextInputBox.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "TextInputBox.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#ifndef ORIGINAL_CODE
|
||||
|
||||
TextInputBox::TextInputBox(int id, int x, int y) :
|
||||
TextInputBox(id, x, y, 200, 12, "", "")
|
||||
{
|
||||
}
|
||||
|
||||
TextInputBox::TextInputBox(int id, int x, int y, int width, int height) :
|
||||
TextInputBox(id, x, y, width, height, "", "")
|
||||
{
|
||||
}
|
||||
|
||||
TextInputBox::TextInputBox(int id, int x, int y, int width, int height, const std::string& placeholder) :
|
||||
TextInputBox(id, x, y, width, height, placeholder, "")
|
||||
{
|
||||
}
|
||||
|
||||
TextInputBox::TextInputBox(int id, int x, int y, int width, int height, const std::string& placeholder, const std::string& text) :
|
||||
m_ID(id),
|
||||
m_xPos(x),
|
||||
m_yPos(y),
|
||||
m_width(width),
|
||||
m_height(height),
|
||||
m_placeholder(placeholder),
|
||||
m_text(text)
|
||||
{
|
||||
}
|
||||
|
||||
void TextInputBox::init(Font* pFont)
|
||||
{
|
||||
m_pFont = pFont;
|
||||
}
|
||||
|
||||
void TextInputBox::setEnabled(bool bEnabled)
|
||||
{
|
||||
m_bEnabled = true;
|
||||
}
|
||||
|
||||
void TextInputBox::keyPressed(Minecraft* minecraft, int key)
|
||||
{
|
||||
if (!m_bFocused)
|
||||
return;
|
||||
|
||||
bool bShiftPressed = minecraft->platform()->shiftPressed();
|
||||
|
||||
char chr = '\0';
|
||||
if (key >= AKEYCODE_A && key <= AKEYCODE_Z)
|
||||
{
|
||||
chr = char((key - AKEYCODE_A) + (bShiftPressed ? 'A' : 'a'));
|
||||
}
|
||||
if (key >= AKEYCODE_0 && key <= AKEYCODE_9)
|
||||
{
|
||||
static const char shiftmap[] = { ')', '!', '@', '#', '$', '%', '^', '&', '*', '(' };
|
||||
chr = char(bShiftPressed ? shiftmap[key - AKEYCODE_0] : (key - AKEYCODE_0 + '0'));
|
||||
}
|
||||
switch (key)
|
||||
{
|
||||
case AKEYCODE_DEL:
|
||||
chr = '\b';
|
||||
break;
|
||||
case AKEYCODE_FORWARD_DEL:
|
||||
chr = '\001';
|
||||
break;
|
||||
case AKEYCODE_ARROW_LEFT:
|
||||
chr = '\002';
|
||||
break;
|
||||
case AKEYCODE_ARROW_RIGHT:
|
||||
chr = '\003';
|
||||
break;
|
||||
case AKEYCODE_SPACE:
|
||||
chr = ' ';
|
||||
break;
|
||||
case AKEYCODE_COMMA:
|
||||
chr = bShiftPressed ? '<' : ',';
|
||||
break;
|
||||
case AKEYCODE_PERIOD:
|
||||
chr = bShiftPressed ? '>' : '.';
|
||||
break;
|
||||
case AKEYCODE_PLUS:
|
||||
chr = bShiftPressed ? '+' : '=';
|
||||
break;
|
||||
case AKEYCODE_MINUS:
|
||||
chr = bShiftPressed ? '_' : '-';
|
||||
break;
|
||||
case AKEYCODE_SEMICOLON:
|
||||
chr = bShiftPressed ? ':' : ';';
|
||||
break;
|
||||
case AKEYCODE_SLASH:
|
||||
chr = bShiftPressed ? '?' : '/';
|
||||
break;
|
||||
case AKEYCODE_GRAVE:
|
||||
chr = bShiftPressed ? '~' : '`';
|
||||
break;
|
||||
case AKEYCODE_BACKSLASH:
|
||||
chr = bShiftPressed ? '|' : '\\';
|
||||
break;
|
||||
case AKEYCODE_APOSTROPHE:
|
||||
chr = bShiftPressed ? '"' : '\'';
|
||||
break;
|
||||
case AKEYCODE_LEFT_BRACKET:
|
||||
chr = bShiftPressed ? '{' : '[';
|
||||
break;
|
||||
case AKEYCODE_RIGHT_BRACKET:
|
||||
chr = bShiftPressed ? '}' : ']';
|
||||
break;
|
||||
}
|
||||
|
||||
if (chr)
|
||||
charPressed(chr);
|
||||
}
|
||||
|
||||
void TextInputBox::tick()
|
||||
{
|
||||
if (!m_lastFlashed)
|
||||
m_lastFlashed = getTimeMs();
|
||||
|
||||
if (m_bFocused)
|
||||
{
|
||||
if (getTimeMs() > m_lastFlashed + 500)
|
||||
{
|
||||
m_lastFlashed += 500;
|
||||
m_bCursorOn ^= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bCursorOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TextInputBox::setFocused(bool b)
|
||||
{
|
||||
if (m_bFocused == b)
|
||||
return;
|
||||
|
||||
m_bFocused = b;
|
||||
if (b)
|
||||
{
|
||||
m_lastFlashed = getTimeMs();
|
||||
m_bCursorOn = true;
|
||||
m_insertHead = int(m_text.size());
|
||||
}
|
||||
}
|
||||
|
||||
void TextInputBox::onClick(int x, int y)
|
||||
{
|
||||
setFocused(clicked(x, y));
|
||||
}
|
||||
|
||||
void TextInputBox::charPressed(int k)
|
||||
{
|
||||
if (!m_bFocused)
|
||||
return;
|
||||
|
||||
if (k == '\b')
|
||||
{
|
||||
if (m_text.empty())
|
||||
return;
|
||||
|
||||
if (m_insertHead <= 0)
|
||||
return;
|
||||
|
||||
if (m_insertHead > int(m_text.size()))
|
||||
m_insertHead = int(m_text.size());
|
||||
|
||||
m_text.erase(m_text.begin() + m_insertHead - 1, m_text.begin() + m_insertHead);
|
||||
m_insertHead--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (k == '\001') // delete
|
||||
{
|
||||
if (m_text.empty())
|
||||
return;
|
||||
|
||||
if (m_insertHead < 0)
|
||||
return;
|
||||
|
||||
if (m_insertHead >= int(m_text.size()))
|
||||
return;
|
||||
|
||||
m_text.erase(m_text.begin() + m_insertHead, m_text.begin() + m_insertHead + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (k == '\002') // left
|
||||
{
|
||||
m_insertHead--;
|
||||
if (m_insertHead < 0)
|
||||
m_insertHead = 0;
|
||||
}
|
||||
|
||||
if (k == '\003') // right
|
||||
{
|
||||
m_insertHead++;
|
||||
if (!m_text.empty())
|
||||
{
|
||||
if (m_insertHead > int(m_text.size()))
|
||||
m_insertHead = int(m_text.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_insertHead = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (k == '\n' || k == '\r')
|
||||
{
|
||||
m_bFocused = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// other unrenderable character?
|
||||
if (k < ' ' || k > '~')
|
||||
return;
|
||||
|
||||
// note: the width will increase by the same amount no matter where K is appended
|
||||
int width = m_pFont->width(m_text + char(k));
|
||||
if (width < m_width - 2)
|
||||
{
|
||||
m_text.insert(m_text.begin() + m_insertHead, k);
|
||||
m_insertHead++;
|
||||
}
|
||||
}
|
||||
|
||||
void TextInputBox::render()
|
||||
{
|
||||
fill(m_xPos, m_yPos, m_xPos + m_width, m_yPos + m_height, 0xFFAAAAAA);
|
||||
fill(m_xPos + 1, m_yPos + 1, m_xPos + m_width - 1, m_yPos + m_height - 1, 0xFF000000);
|
||||
|
||||
int textYPos = (m_height - 8) / 2;
|
||||
|
||||
if (m_text.empty())
|
||||
drawString(m_pFont, m_placeholder, m_xPos + 2, m_yPos + 2, 0x404040);
|
||||
else
|
||||
drawString(m_pFont, m_text, m_xPos + 2, m_yPos + textYPos, 0xFFFFFF);
|
||||
|
||||
if (m_bCursorOn)
|
||||
{
|
||||
int xPos = 2;
|
||||
|
||||
std::string substr = m_text.substr(0, m_insertHead);
|
||||
xPos += m_pFont->width(substr);
|
||||
|
||||
drawString(m_pFont, "_", m_xPos + xPos, m_yPos + textYPos + 2, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextInputBox::clicked(int xPos, int yPos)
|
||||
{
|
||||
if (!m_bEnabled) return false;
|
||||
|
||||
if (xPos < m_xPos) return false;
|
||||
if (yPos < m_yPos) return false;
|
||||
if (xPos >= m_xPos + m_width) return false;
|
||||
if (yPos >= m_yPos + m_height) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
54
source/client/gui/components/TextInputBox.hpp
Normal file
54
source/client/gui/components/TextInputBox.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utils.hpp"
|
||||
#include "GuiComponent.hpp"
|
||||
|
||||
class Minecraft;
|
||||
|
||||
// @NOTE: This is NOT original Mojang code.
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
|
||||
class TextInputBox : public GuiComponent
|
||||
{
|
||||
public:
|
||||
TextInputBox(int id, int x, int y);
|
||||
TextInputBox(int id, int x, int y, int width, int height);
|
||||
TextInputBox(int id, int x, int y, int width, int height, const std::string& placeholder);
|
||||
TextInputBox(int id, int x, int y, int width, int height, const std::string& placeholder, const std::string& text);
|
||||
|
||||
void init(Font* pFont);
|
||||
void setEnabled(bool bEnabled);
|
||||
void keyPressed(Minecraft*, int key);
|
||||
void charPressed(int chr);
|
||||
void render();
|
||||
void tick();
|
||||
void setFocused(bool b);
|
||||
void onClick(int x, int y);
|
||||
bool clicked(int x, int y);
|
||||
|
||||
public:
|
||||
int m_ID = 0;
|
||||
int m_xPos = 0;
|
||||
int m_yPos = 0;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
std::string m_placeholder;
|
||||
std::string m_text;
|
||||
bool m_bFocused = false;
|
||||
bool m_bEnabled = true;
|
||||
bool m_bCursorOn = true;
|
||||
int m_insertHead = 0;
|
||||
int m_lastFlashed = 0;
|
||||
Font* m_pFont = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
217
source/client/gui/components/WorldSelectionList.cpp
Normal file
217
source/client/gui/components/WorldSelectionList.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#include "WorldSelectionList.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
static float WorldSelectionList_Static1(float a, float b, float c, float d)
|
||||
{
|
||||
float x1 = 2 * (a / b), x2;
|
||||
|
||||
if (x1 < 1.0f)
|
||||
x2 = c + ((d - c) * 0.5f) * x1 * x1;
|
||||
else
|
||||
x2 = c + ((d - c) * -0.5f) * ((x1 - 1.0f) * (x1 - 3.0f) - 1.0f);
|
||||
|
||||
return x2;
|
||||
}
|
||||
|
||||
WorldSelectionList::WorldSelectionList(Minecraft* minecraft, int a, int b) :
|
||||
RolledSelectionList(minecraft, a, b, 0, a, 26, b - 32, 120)
|
||||
{
|
||||
field_68 = b;
|
||||
}
|
||||
|
||||
bool WorldSelectionList::capXPosition()
|
||||
{
|
||||
if (RolledSelectionList::capXPosition())
|
||||
{
|
||||
field_D8 = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void WorldSelectionList::tick()
|
||||
{
|
||||
RolledSelectionList::tick();
|
||||
field_D0++;
|
||||
if (Mouse::_buttonStates[1] || !field_28)
|
||||
return;
|
||||
|
||||
m_selectedIndex = -1;
|
||||
if (field_D8 == 1)
|
||||
{
|
||||
field_54 += 1.0f;
|
||||
if (field_54 != field_58)
|
||||
{
|
||||
tweenInited();
|
||||
return;
|
||||
}
|
||||
|
||||
field_D8 = 0;
|
||||
field_38 = 0.0f;
|
||||
field_34 = field_30 = field_60;
|
||||
m_selectedIndex = getItemAtPosition(field_18 / 2, field_1C / 2);
|
||||
return;
|
||||
}
|
||||
|
||||
float abs_field38 = Mth::abs(field_38);
|
||||
if (abs_field38 >= 5.0f)
|
||||
{
|
||||
field_38 *= 0.9f;
|
||||
return;
|
||||
}
|
||||
|
||||
field_38 *= 0.8f;
|
||||
if (abs_field38 < 1.0f && field_28 < 0)
|
||||
{
|
||||
float x1 = float((field_18 - m_itemWidth) / 2) + field_30;
|
||||
int x2 = getItemAtXPositionRaw(int(x1 - 10.0f * field_38));
|
||||
float x3 = float(m_itemWidth * x2) - x1;
|
||||
|
||||
if (x3 < -float(m_itemWidth / 2))
|
||||
x3 += float(m_itemWidth);
|
||||
|
||||
if (Mth::abs(x3) > 1.0f || abs_field38 >= 0.1f)
|
||||
{
|
||||
field_5C = field_30;
|
||||
field_60 = field_30 + x3;
|
||||
field_54 = 0.0f;
|
||||
field_D8 = 1;
|
||||
field_58 = float(Mth::Min(7, int(float(0.25f * Mth::abs(x3))) + 1));
|
||||
|
||||
tweenInited();
|
||||
return;
|
||||
}
|
||||
|
||||
m_selectedIndex = getItemAtPosition(field_18 / 2, field_1C / 2);
|
||||
}
|
||||
}
|
||||
|
||||
int WorldSelectionList::getNumberOfItems()
|
||||
{
|
||||
return int(m_items.size());
|
||||
}
|
||||
|
||||
void WorldSelectionList::selectItem(int index, bool b)
|
||||
{
|
||||
if (m_selectedIndex >= 0 && m_selectedIndex == index && !field_90)
|
||||
{
|
||||
field_90 = 1;
|
||||
m_levelSummary = m_items[index];
|
||||
}
|
||||
}
|
||||
|
||||
bool WorldSelectionList::isSelectedItem(int index)
|
||||
{
|
||||
return m_selectedIndex == index;
|
||||
}
|
||||
|
||||
float WorldSelectionList::getPos(float f)
|
||||
{
|
||||
if (field_D8 != 1)
|
||||
return RolledSelectionList::getPos(f);
|
||||
|
||||
return Lerp(WorldSelectionList_Static1(field_54, field_58, field_5C, field_60),
|
||||
WorldSelectionList_Static1(field_54 + 1.0f, field_58, field_5C, field_60),
|
||||
f);
|
||||
}
|
||||
|
||||
void WorldSelectionList::touched()
|
||||
{
|
||||
field_D8 = false;
|
||||
}
|
||||
|
||||
void WorldSelectionList::renderItem(int index, int xPos, int yPos, int width, Tesselator& t)
|
||||
{
|
||||
int xCenter = xPos + m_itemWidth / 2;
|
||||
float mult = Max(1.1f - 0.0055f * float(abs(field_18 / 2 - xCenter)), 0.2f);
|
||||
if (mult > 1.0f)
|
||||
mult = 1.0f;
|
||||
|
||||
int color1 = 0x010101 * int(mult * 255.0f);
|
||||
int color2 = 0x010101 * int(mult * 140.0f);
|
||||
|
||||
std::vector<std::string> details = m_vvs[index];
|
||||
|
||||
drawString(m_pMinecraft->m_pFont, details[0], xCenter + 5 - m_itemWidth / 2, yPos + 50, color1);
|
||||
drawString(m_pMinecraft->m_pFont, details[1], xCenter + 5 - m_itemWidth / 2, yPos + 60, color2);
|
||||
drawString(m_pMinecraft->m_pFont, details[2], xCenter + 5 - m_itemWidth / 2, yPos + 70, color2);
|
||||
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture(m_previewImages[index]);
|
||||
|
||||
// @NOTE: useless assignment of color
|
||||
t.color(0.3f, 1.0f, 0.2f);
|
||||
|
||||
t.begin();
|
||||
t.color(color1);
|
||||
float y = float(yPos) - 6.0f;
|
||||
t.vertexUV(float(xCenter - 32), y, this->field_4, 0.0f, 0.0f);
|
||||
t.vertexUV(float(xCenter - 32), y + 48.0f, this->field_4, 0.0f, 1.0f);
|
||||
t.vertexUV(float(xCenter + 32), y + 48.0f, this->field_4, 1.0f, 1.0f);
|
||||
t.vertexUV(float(xCenter + 32), y, this->field_4, 1.0f, 0.0f);
|
||||
t.draw();
|
||||
}
|
||||
|
||||
void WorldSelectionList::renderBackground()
|
||||
{
|
||||
}
|
||||
|
||||
void WorldSelectionList::commit()
|
||||
{
|
||||
for (const auto& item : m_items)
|
||||
{
|
||||
// @NOTE: this string stream crap is unused.
|
||||
// Weirdly Java Edition Beta 1.3 did not have world previews, so its interesting to see PE try
|
||||
std::stringstream ss;
|
||||
ss << item.field_18 << "/preview.png";
|
||||
|
||||
m_previewImages.push_back("gui/default_world.png");
|
||||
|
||||
std::vector<std::string> vs;
|
||||
vs.push_back(item.field_18);
|
||||
vs.push_back(m_pMinecraft->platform()->getDateString(item.field_30));
|
||||
vs.push_back(item.field_0);
|
||||
m_vvs.push_back(vs);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSelectionList::stepLeft()
|
||||
{
|
||||
if (m_selectedIndex <= 0)
|
||||
return;
|
||||
|
||||
field_5C = field_30;
|
||||
field_D8 = 1;
|
||||
field_60 = field_5C - float(m_itemWidth);
|
||||
field_54 = 0.0f;
|
||||
field_58 = 8.0f;
|
||||
tweenInited();
|
||||
}
|
||||
|
||||
void WorldSelectionList::stepRight()
|
||||
{
|
||||
if (m_selectedIndex < 0 || m_selectedIndex >= getNumberOfItems() - 1)
|
||||
return;
|
||||
|
||||
field_5C = field_30;
|
||||
field_D8 = 1;
|
||||
field_60 = field_5C + float(m_itemWidth);
|
||||
field_54 = 0.0f;
|
||||
field_58 = 8.0f;
|
||||
tweenInited();
|
||||
}
|
||||
|
||||
void WorldSelectionList::tweenInited()
|
||||
{
|
||||
field_38 =
|
||||
WorldSelectionList_Static1(field_54, field_58, field_5C, field_60) -
|
||||
WorldSelectionList_Static1(field_54 + 1.0f, field_58, field_5C, field_60);
|
||||
}
|
||||
50
source/client/gui/components/WorldSelectionList.hpp
Normal file
50
source/client/gui/components/WorldSelectionList.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/********************************************************************
|
||||
Minecraft: Pocket Edition - Decompilation Project
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RolledSelectionList.hpp"
|
||||
|
||||
class WorldSelectionList : public RolledSelectionList
|
||||
{
|
||||
public:
|
||||
WorldSelectionList(Minecraft*, int, int);
|
||||
|
||||
bool capXPosition() override;
|
||||
void tick() override;
|
||||
int getNumberOfItems() override;
|
||||
void selectItem(int, bool) override;
|
||||
bool isSelectedItem(int) override;
|
||||
float getPos(float) override;
|
||||
void touched() override;
|
||||
void renderItem(int, int, int, int, Tesselator&) override;
|
||||
void renderBackground() override;
|
||||
|
||||
void commit();
|
||||
void stepLeft();
|
||||
void stepRight();
|
||||
void tweenInited();
|
||||
|
||||
public:
|
||||
float field_54;
|
||||
float field_58;
|
||||
float field_5C;
|
||||
float field_60;
|
||||
int m_selectedIndex;
|
||||
int field_68;
|
||||
std::vector<LevelSummary> m_items;
|
||||
std::vector<std::vector<std::string> > m_vvs;
|
||||
std::vector<std::string> m_previewImages;
|
||||
bool field_90 = false;
|
||||
LevelSummary m_levelSummary;
|
||||
int field_CC = -1;
|
||||
int field_D0 = 0;
|
||||
int field_D4;
|
||||
int field_D8 = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user