forked from Kolyah35/minecraft-pe-0.6.1
353 lines
8.8 KiB
C++
Executable File
353 lines
8.8 KiB
C++
Executable File
#include "RolledSelectionListV.h"
|
|
#include "../../Minecraft.h"
|
|
#include "../../renderer/Tesselator.h"
|
|
#include "../../renderer/gles.h"
|
|
#include "../../../platform/input/Mouse.h"
|
|
#include "../../../util/Mth.h"
|
|
#include "../../renderer/Textures.h"
|
|
|
|
|
|
RolledSelectionListV::RolledSelectionListV( Minecraft* minecraft_, int width_, int height_, int x0_, int x1_, int y0_, int y1_, int itemHeight_ )
|
|
: minecraft(minecraft_),
|
|
width(width_),
|
|
height(height_),
|
|
x0((float)x0_),
|
|
x1((float)x1_),
|
|
y0((float)y0_),
|
|
y1((float)y1_),
|
|
itemHeight(itemHeight_),
|
|
selectionY(-1),
|
|
lastSelectionTime(0),
|
|
lastSelection(-1),
|
|
renderSelection(true),
|
|
doRenderHeader(false),
|
|
headerHeight(0),
|
|
dragState(DRAG_OUTSIDE),
|
|
yDrag(0.0f),
|
|
yo(0.0f),
|
|
yoo(0.0f),
|
|
yInertia(0.0f),
|
|
_componentSelected(false),
|
|
_renderDirtBackground(true),
|
|
_renderTopBorder(true),
|
|
_renderBottomBorder(true),
|
|
_lastyoo(0),
|
|
_yinertia(0),
|
|
_stickPixels(0),
|
|
_lastxm(0),
|
|
_lastym(0)
|
|
{
|
|
yo = yoo = 0;//(float)(-itemHeight) * 0.5f;
|
|
_lastyoo = yoo;
|
|
}
|
|
|
|
void RolledSelectionListV::setRenderSelection( bool _renderSelection )
|
|
{
|
|
renderSelection = _renderSelection;
|
|
}
|
|
|
|
void RolledSelectionListV::setComponentSelected(bool selected) {
|
|
_componentSelected = selected;
|
|
}
|
|
|
|
void RolledSelectionListV::setRenderHeader( bool _renderHeader, int _headerHeight )
|
|
{
|
|
doRenderHeader = _renderHeader;
|
|
headerHeight = _headerHeight;
|
|
|
|
if (!doRenderHeader) {
|
|
headerHeight = 0;
|
|
}
|
|
}
|
|
|
|
int RolledSelectionListV::getMaxPosition()
|
|
{
|
|
return getNumberOfItems() * itemHeight + headerHeight;
|
|
}
|
|
|
|
int RolledSelectionListV::getItemAtPosition( int x, int y )
|
|
{
|
|
int clickSlotPos = (int)(y - y0 - headerHeight + (int) yo - 4);
|
|
int isInsideX = x >= x0 && x <= x1;
|
|
return isInsideX? getItemAtYPositionRaw(clickSlotPos) : -1;
|
|
}
|
|
|
|
int RolledSelectionListV::getItemAtYPositionRaw(int y) {
|
|
int slot = y / itemHeight;
|
|
bool isInsideX = slot >= 0 && y >= 0 && slot < getNumberOfItems();
|
|
return isInsideX? slot : -1;
|
|
}
|
|
|
|
bool RolledSelectionListV::capYPosition()
|
|
{
|
|
float max = getMaxPosition() - (y1 - y0 - 4);
|
|
if (max < 0) max /= 2;
|
|
if (yo < 0) yo = 0;
|
|
if (yo > max) yo = max;
|
|
return false;
|
|
/*
|
|
const float MinY = -itemHeight/2;//(float)(itemHeight-height)/2;
|
|
const float MaxY = MinY + (getNumberOfItems()-1) * itemHeight;
|
|
if (yo < MinY) { yo = MinY; yInertia = 0; return true; }
|
|
if (yo > MaxY) { yo = MaxY; yInertia = 0; return true; }
|
|
return false;
|
|
*/
|
|
}
|
|
|
|
void RolledSelectionListV::tick() {
|
|
|
|
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT))
|
|
{
|
|
_yinertia = _lastyoo - yoo;
|
|
}
|
|
_lastyoo = yoo;
|
|
|
|
//yInertia = Mth::absDecrease(yInertia, 1.0f, 0);
|
|
|
|
yoo = yo - yInertia;
|
|
|
|
//LOGI("tick: %f, %f, %f\n", yo, yInertia, _yinertia);
|
|
}
|
|
|
|
float RolledSelectionListV::getPos(float alpha) {
|
|
return yoo - yInertia * alpha;
|
|
}
|
|
|
|
void RolledSelectionListV::render( int xm, int ym, float a )
|
|
{
|
|
_lastxm = xm;
|
|
_lastym = ym;
|
|
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 = convertSelection( getItemAtPosition(width/2, ym), xm, ym );
|
|
selectStart(lastSelection);
|
|
//LOGI("Sel : %d\n", lastSelection);
|
|
selectionY = ym;
|
|
_stickPixels = 10;
|
|
}
|
|
else if (dragState >= 0) {
|
|
float delta = (ym - yDrag);
|
|
float absDelta = Mth::abs(delta);
|
|
if (absDelta > _stickPixels) {
|
|
_stickPixels = 0;
|
|
delta -= delta>0? _stickPixels : -_stickPixels;
|
|
} else {
|
|
delta = 0;
|
|
_stickPixels -= absDelta;
|
|
}
|
|
yo -= delta;
|
|
yoo = yo;
|
|
}
|
|
dragState = DRAG_NORMAL;
|
|
}
|
|
} else {
|
|
if (dragState >= 0) {
|
|
if (dragState >= 0) {
|
|
yInertia = _yinertia < 0? Mth::Max(-10.0f, _yinertia) : Mth::Min(10.0f, _yinertia);
|
|
}
|
|
// kill small inertia values when releasing scrollist
|
|
if (std::abs(yInertia) <= 2.0001f) {
|
|
yInertia = 0.0f;
|
|
}
|
|
|
|
if (std::abs(yInertia) <= 10 /*&& getTimeMs() - lastSelectionTime < 300 */)
|
|
{
|
|
//float clickSlotPos = (ym - x0 - headerHeight + (int) yo - 4);
|
|
int slot = convertSelection( getItemAtPosition(width/2, ym), xm, ym);
|
|
//LOGI("slot: %d, lt: %d. diff: %d - %d\n", slot, lastSelection, selectionX, xm);
|
|
if (xm >= x0 && xm <= x1 && slot >= 0 && slot == lastSelection && std::abs(selectionY - ym) < 10)
|
|
selectItem(slot, false);
|
|
} else {
|
|
selectCancel();
|
|
}
|
|
}
|
|
|
|
// if (slot >= 0 && std::abs(selectionX - xm) < itemWidth)
|
|
// {
|
|
// bool doubleClick = false;
|
|
// selectItem(slot, doubleClick);
|
|
// //xInertia = 0.0f;
|
|
// }
|
|
//}
|
|
dragState = NO_DRAG;
|
|
|
|
yo = getPos(a);
|
|
}
|
|
yDrag = (float)ym;
|
|
|
|
evaluate(xm, ym);
|
|
capYPosition();
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
const int HalfWidth = 48;
|
|
int rowX = (int)(width / 2 - HalfWidth + 8);
|
|
int rowBaseY = (int)(y0 + 4 - (int) yo);
|
|
|
|
if (_renderDirtBackground)
|
|
renderDirtBackground();
|
|
|
|
if (getNumberOfItems() == 0) yo = 0;
|
|
|
|
//int rowY = (int)(height / 2 - HalfHeight + 8);
|
|
if (doRenderHeader) {
|
|
const int HalfWidth = 48;
|
|
int rowX = (int)(width / 2 - HalfWidth + 8);
|
|
int rowBaseY = (int)(y0 + 4 - (int) yo);
|
|
renderHeader(rowX, rowBaseY, t);
|
|
}
|
|
|
|
onPreRender();
|
|
for (int i = 0; i < itemCount; i++) {
|
|
|
|
float y = (float)(rowBaseY + (i) * itemHeight + headerHeight);
|
|
float h = itemHeight - 4.0f;
|
|
|
|
if (y > y1 || (y + h) < y0) {
|
|
continue;
|
|
}
|
|
|
|
if (renderSelection && isSelectedItem(i)) {
|
|
//float y0 = height / 2.0f - HalfHeight - 4;
|
|
//float y1 = height / 2.0f + HalfHeight - 4;
|
|
//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 - 2 - ew, y0 - ew, 0);
|
|
//t.vertex(x - 2 - ew, y1 + ew, 0);
|
|
//t.vertex(x + h + 2 + ew, y1 + ew, 0);
|
|
//t.vertex(x + h + 2 + ew, y0 - ew, 0);
|
|
|
|
//t.color(0x000000);
|
|
//t.vertex(x - 1, y0 + 1, 0);
|
|
//t.vertex(x - 1, y1 - 1, 0);
|
|
//t.vertex(x + h + 1, y1 - 1, 0);
|
|
//t.vertex(x + h + 1, y0 + 1, 0);
|
|
|
|
//t.draw();
|
|
//glEnable2(GL_TEXTURE_2D);
|
|
}
|
|
renderItem(i, rowX, (int)y, (int)h, t);
|
|
}
|
|
onPostRender();
|
|
|
|
glDisable2(GL_DEPTH_TEST);
|
|
|
|
if (_renderTopBorder)
|
|
renderHoleBackground(0, y0, 255, 255);
|
|
if (_renderBottomBorder)
|
|
renderHoleBackground(y1, (float)height, 255, 255);
|
|
renderForeground();
|
|
|
|
//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 RolledSelectionListV::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 RolledSelectionListV::touched()
|
|
{
|
|
}
|
|
|
|
void RolledSelectionListV::evaluate(int xm, int ym)
|
|
{
|
|
if (std::abs(selectionY - ym) >= 10) {
|
|
lastSelection = -1;
|
|
selectCancel();
|
|
}
|
|
}
|
|
|
|
void RolledSelectionListV::onPreRender()
|
|
{
|
|
}
|
|
|
|
void RolledSelectionListV::onPostRender()
|
|
{
|
|
}
|
|
|
|
void RolledSelectionListV::renderDirtBackground()
|
|
{
|
|
float by0 = _renderTopBorder? y0 : 0;
|
|
float by1 = _renderBottomBorder? y1 : height;
|
|
|
|
minecraft->textures->loadAndBindTexture("gui/background.png");
|
|
glColor4f2(1.0f, 1, 1, 1);
|
|
float s = 32;
|
|
const float uvy = (float)((int) yo);
|
|
Tesselator& t = Tesselator::instance;
|
|
t.begin();
|
|
t.color(0x202020);
|
|
t.vertexUV(x0, by1, 0, x0 / s, (by1+uvy) / s);
|
|
t.vertexUV(x1, by1, 0, x1 / s, (by1+uvy) / s);
|
|
t.vertexUV(x1, by0, 0, x1 / s, (by0+uvy) / s);
|
|
t.vertexUV(x0, by0, 0, x0 / s, (by0+uvy) / s);
|
|
t.draw();
|
|
//LOGI("%f, %f - %f, %f\n", x0, by0, x1, by1);
|
|
}
|