Files
minecraft-pe-0.6.1/src/client/gui/components/RolledSelectionListH.cpp
2026-03-02 22:04:18 +03:00

300 lines
7.7 KiB
C++
Executable File

#include "RolledSelectionListH.h"
#include "../../Minecraft.h"
#include "../../renderer/Tesselator.h"
#include "../../renderer/gles.h"
#include "../../../platform/input/Mouse.h"
#include "../../../platform/input/Multitouch.h"
#include "../../../util/Mth.h"
#include "../../renderer/Textures.h"
RolledSelectionListH::RolledSelectionListH( Minecraft* minecraft, int width, int height, int x0, int x1, int y0, int y1, int itemWidth )
: minecraft(minecraft),
width(width),
height(height),
x0((float)x0),
x1((float)x1),
y0((float)y0),
y1((float)y1),
itemWidth(itemWidth),
selectionX(-1),
lastSelectionTime(0),
lastSelection(-1),
renderSelection(true),
doRenderHeader(false),
headerWidth(0),
dragState(DRAG_OUTSIDE),
xDrag(0.0f),
xo(0.0f),
xoo(0.0f),
xInertia(0.0f),
_componentSelected(false),
_renderTopBorder(true),
_renderBottomBorder(true),
_lastxoo(0),
_xinertia(0)
{
xo = xoo = (float)(itemWidth-width) * 0.5f;
_lastxoo = xoo;
}
void RolledSelectionListH::setRenderSelection( bool _renderSelection )
{
renderSelection = _renderSelection;
}
void RolledSelectionListH::setComponentSelected(bool selected) {
_componentSelected = selected;
}
void RolledSelectionListH::setRenderHeader( bool _renderHeader, int _headerHeight )
{
doRenderHeader = _renderHeader;
headerWidth = _headerHeight;
if (!doRenderHeader) {
headerWidth = 0;
}
}
int RolledSelectionListH::getMaxPosition()
{
return getNumberOfItems() * itemWidth + headerWidth;
}
int RolledSelectionListH::getItemAtPosition( int x, int y )
{
int clickSlotPos = (int)(x - x0 - headerWidth + (int) xo - 4);
int isInsideY = y >= y0 && y <= y1;
return isInsideY? getItemAtXPositionRaw(clickSlotPos) : -1;
}
int RolledSelectionListH::getItemAtXPositionRaw(int x) {
int slot = x / itemWidth;
bool isInsideX = slot >= 0 && x >= 0 && slot < getNumberOfItems();
return isInsideX? slot : -1;
}
bool RolledSelectionListH::capXPosition()
{
const float MinX = (float)(itemWidth-width)/2;
const float MaxX = MinX + (getNumberOfItems()-1) * itemWidth;
if (xo < MinX) { xo = MinX; xInertia = 0; return true; }
if (xo > MaxX) { xo = MaxX; xInertia = 0; return true; }
return false;
}
void RolledSelectionListH::tick() {
//if (Mouse::isButtonDown(MouseAction::ACTION_LEFT))
{
_xinertia = _lastxoo - xoo;
}
_lastxoo = xoo;
xoo = xo - xInertia;
}
float RolledSelectionListH::getPos(float alpha) {
return xoo - xInertia * alpha;
}
void RolledSelectionListH::render( int xm, int ym, float a )
{
renderBackground();
int itemCount = getNumberOfItems();
//float yy0 = height / 2.0f + 124;
//float yy1 = yy0 + 6;
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
touched();
//LOGI("DOWN ym: %d\n", ym);
if (ym >= y0 && ym <= y1) {
if (dragState == NO_DRAG) {
lastSelectionTime = getTimeMs();
lastSelection = getItemAtPosition(xm, height/2);
//float localX = (float)(xm*Gui::InvGuiScale - x0 - xo + lastSelection * itemWidth + headerWidth);
selectStart(lastSelection, 0, 0);//localX, ym-y0);
selectionX = xm;
}
else if (dragState >= 0) {
xo -= (xm - xDrag);
xoo = xo;
}
dragState = DRAG_NORMAL;
//const int* ids;
//LOGI("mtouch: %d\n", Multitouch::getActivePointerIds(&ids));
}
} else {
if (dragState >= 0) {
if (dragState >= 0) {
xInertia = _xinertia < 0? Mth::Max(-20.0f, _xinertia) : Mth::Min(20.0f, _xinertia);
}
//LOGI("Inertia: %f. Time: %d, delta-x: %d, (xm, sel: %d, %d)\n", xInertia, getTimeMs() - lastSelectionTime, std::abs(selectionX - xm), xm, selectionX);
// kill small inertia values when releasing scrollist
if (std::abs(xInertia) <= 2.0001f) {
xInertia = 0.0f;
}
if (std::abs(xInertia) <= 10 && getTimeMs() - lastSelectionTime < 300)
{
int slot = getItemAtPosition(xm, height/2);
//LOGI("slot: %d, lt: %d. diff: %d - %d\n", slot, lastSelection, selectionX, xm);
if (slot >= 0 && slot == lastSelection && std::abs(selectionX - xm) < 10)
selectItem(slot, false);
else
selectCancel();
} else {
selectCancel();
}
}
// if (slot >= 0 && std::abs(selectionX - xm) < itemWidth)
// {
// bool doubleClick = false;
// selectItem(slot, doubleClick);
// //xInertia = 0.0f;
// }
//}
dragState = NO_DRAG;
xo = getPos(a);
}
xDrag = (float)xm;
capXPosition();
Tesselator& t = Tesselator::instance;
float by0 = _renderTopBorder? y0 : 0;
float by1 = _renderBottomBorder? y1 : height;
//LOGI("x: %f\n", xo);
minecraft->textures->loadAndBindTexture("gui/background.png");
glColor4f2(1.0f, 1, 1, 1);
float s = 32;
t.begin();
t.color(0x202020);
t.vertexUV(x0, by1, 0, (x0 + (int) xo) / s, by1 / s);
t.vertexUV(x1, by1, 0, (x1 + (int) xo) / s, by1 / s);
t.vertexUV(x1, by0, 0, (x1 + (int) xo) / s, by0 / s);
t.vertexUV(x0, by0, 0, (x0 + (int) xo) / s, by0 / s);
t.draw();
const int HalfHeight = 48;
if (getNumberOfItems() == 0) xo = 0;
int rowY = (int)(height / 2 - HalfHeight + 8);
int rowBaseX = (int)(x0 /*+ 4*/ - (int) xo);
if (doRenderHeader) {
renderHeader(rowBaseX, rowY, t);
}
for (int i = 0; i < itemCount; i++) {
float x = (float)(rowBaseX + (i) * itemWidth + headerWidth);
float h = (float)itemWidth;
if (x > x1 || (x + h) < x0) {
continue;
}
if (renderSelection && isSelectedItem(i)) {
float y0 = height / 2.0f - HalfHeight - 4; //@kindle-res:+2
float y1 = height / 2.0f + HalfHeight - 4; //@kindle-res:-6
glColor4f2(1, 1, 1, 1);
glDisable2(GL_TEXTURE_2D);
int ew = 0;
int color = 0x808080;
if (_componentSelected) {
ew = 0;
color = 0x7F89BF;
}
t.begin();
t.color(color);
t.vertex(x - 1 - ew, y0 - ew, 0);
t.vertex(x - 1 - ew, y1 + ew, 0);
t.vertex(x + h + 1 + ew, y1 + ew, 0);
t.vertex(x + h + 1 + ew, y0 - ew, 0);
t.color(0x000000);
t.vertex(x, y0 + 1, 0);
t.vertex(x, y1 - 1, 0);
t.vertex(x + h, y1 - 1, 0);
t.vertex(x + h, y0 + 1, 0);
t.draw();
glEnable2(GL_TEXTURE_2D);
}
renderItem(i, (int)x, rowY, (int)h, t);
}
glDisable2(GL_DEPTH_TEST);
if (_renderTopBorder)
renderHoleBackground(0, y0, 255, 255);
if (_renderBottomBorder)
renderHoleBackground(y1, (float)height, 255, 255);
//glEnable2(GL_BLEND);
//glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glDisable2(GL_ALPHA_TEST);
//glShadeModel2(GL_SMOOTH);
//glDisable2(GL_TEXTURE_2D);
//const int d = 4;
//t.begin();
//t.color(0x000000, 0);
//t.vertexUV(y0, x0 + d, 0, 0, 1);
//t.vertexUV(y1, x0 + d, 0, 1, 1);
//t.color(0x000000, 255);
//t.vertexUV(y1, x0, 0, 1, 0);
//t.vertexUV(y0, x0, 0, 0, 0);
//t.draw();
//t.begin();
//t.color(0x000000, 255);
//t.vertexUV(y0, x1, 0, 0, 1);
//t.vertexUV(y1, x1, 0, 1, 1);
//t.color(0x000000, 0);
//t.vertexUV(y1, x1 - d, 0, 1, 0);
//t.vertexUV(y0, x1 - d, 0, 0, 0);
//t.draw();
//renderDecorations(xm, ym);
//glEnable2(GL_TEXTURE_2D);
glEnable2(GL_DEPTH_TEST);
//glShadeModel2(GL_FLAT);
//glEnable2(GL_ALPHA_TEST);
//glDisable2(GL_BLEND);
}
void RolledSelectionListH::renderHoleBackground( /*float x0, float x1,*/ float y0, float y1, int a0, int a1 )
{
Tesselator& t = Tesselator::instance;
minecraft->textures->loadAndBindTexture("gui/background.png");
glColor4f2(1.0f, 1, 1, 1);
float s = 32;
t.begin();
t.color(0x505050, a1);
t.vertexUV(0, y1, 0, 0, y1 / s);
t.vertexUV((float)width, y1, 0, width / s, y1 / s);
t.color(0x505050, a0);
t.vertexUV((float)width, y0, 0, width / s, y0 / s);
t.vertexUV(0, y0, 0, 0, y0 / s);
t.draw();
//printf("x, y, x1, y1: %d, %d, %d, %d\n", 0, (int)y0, width, (int)y1);
}
void RolledSelectionListH::touched()
{
}