Merge pull request #724 from UnknownShadow200/MobileInv

Improve inventory (especially for mobile)
This commit is contained in:
UnknownShadow200 2020-09-27 09:30:17 +10:00 committed by GitHub
commit fe44fb336d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 200 additions and 136 deletions

View File

@ -339,9 +339,9 @@ void Drawer2D_MakeTextTexture(struct Texture* tex, struct DrawTextArgs* args) {
}
void Drawer2D_MakeTexture(struct Texture* tex, struct Bitmap* bmp, int width, int height) {
tex->ID = Gfx_CreateTexture(bmp, false, false);
tex->X = 0; tex->Width = width;
tex->Y = 0; tex->Height = height;
tex->ID = Gfx_CreateTexture(bmp, false, false);
tex->Width = width;
tex->Height = height;
tex->uv.U1 = 0.0f; tex->uv.V1 = 0.0f;
tex->uv.U2 = (float)width / (float)bmp->width;

View File

@ -231,8 +231,7 @@ void TextAtlas_AddInt(struct TextAtlas* atlas, int value, struct VertexTextured*
#define Elem_HandlesPointerUp(elem, id, x, y) (elem)->VTABLE->HandlesPointerUp(elem, id, x, y)
#define Elem_HandlesPointerMove(elem, id, x, y) (elem)->VTABLE->HandlesPointerMove(elem, id, x, y)
#define Widget_BuildMesh(widget, vertices) (widget)->VTABLE->BuildMesh(widget, vertices);
#define Widget_Render2(widget, offset) (widget)->VTABLE->Render2(widget, offset);
#define Widget_Layout(widget) (widget)->VTABLE->Reposition(widget);
#define Elem_TryFree(elem) if ((elem)->VTABLE) { Elem_Free(elem); }
#define Widget_BuildMesh(widget, vertices) (widget)->VTABLE->BuildMesh(widget, vertices)
#define Widget_Render2(widget, offset) (widget)->VTABLE->Render2(widget, offset)
#define Widget_Layout(widget) (widget)->VTABLE->Reposition(widget)
#endif

View File

@ -13,6 +13,7 @@ extern struct IGameComponent Inventory_Component;
#define INVENTORY_BLOCKS_PER_HOTBAR 9
/* Number of hotbars that can be selected between */
#define INVENTORY_HOTBARS 9
#define HOTBAR_MAX_INDEX (INVENTORY_BLOCKS_PER_HOTBAR - 1)
CC_VAR extern struct _InventoryData {
/* Stores the currently bound blocks for all hotbars. */

View File

@ -47,8 +47,7 @@ struct LWebTask {
cc_result res; /* Error returned (e.g. for DNS failure) */
int status; /* HTTP return code for the request */
int reqID; /* Unique identifier for this web task. */
String url; /* URL this task is downloading from/uploading to. */
int reqID; /* Unique request identifier for this web task. */
/* Called when task successfully downloaded/uploaded data. */
void (*Handle)(cc_uint8* data, cc_uint32 len);
};
@ -65,7 +64,7 @@ void GetTokenTask_Run(void);
extern struct SignInTaskData {
struct LWebTask Base;
String username; /* Username to sign in as. Changed to case correct username. */
const char* error; /* If sign in fails, the reason as to why. */
const char* error; /* If sign in fails, the reason why. */
cc_bool needMFA; /* need login code for multifactor authentication */
} SignInTask;
void SignInTask_Run(const String* user, const String* pass, const String* mfaCode);

View File

@ -154,7 +154,7 @@ static void Menu_Remove(void* screen, int i) {
struct Screen* s = (struct Screen*)screen;
struct Widget** widgets = s->widgets;
if (widgets[i]) { Elem_TryFree(widgets[i]); }
if (widgets[i]) { Elem_Free(widgets[i]); }
widgets[i] = NULL;
}
@ -2059,7 +2059,7 @@ CC_NOINLINE static void MenuOptionsScreen_Set(struct MenuOptionsScreen* s, int i
}
CC_NOINLINE static void MenuOptionsScreen_FreeExtHelp(struct MenuOptionsScreen* s) {
Elem_TryFree(&s->extHelp);
Elem_Free(&s->extHelp);
s->extHelp.lines = 0;
}
@ -3041,7 +3041,8 @@ static void NostalgiaScreen_InitWidgets(struct MenuOptionsScreen* s) {
s->DoRecreateExtra = NostalgiaScreen_RecreateExtra;
MenuOptionsScreen_InitButtons(s, buttons, Array_Elems(buttons), NostalgiaScreen_SwitchBack);
TextWidget_Make(&nostalgia_desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 100);
TextWidget_Init(&nostalgia_desc);
Widget_SetLocation(&nostalgia_desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 100);
s->widgets[9] = (struct Widget*)&nostalgia_desc;
}
@ -3568,9 +3569,9 @@ static void TouchMore_Chat(void* s, void* w) {
Gui_Remove((struct Screen*)&TouchMoreScreen);
ChatScreen_OpenInput(&String_Empty);
}
static void TouchMore_Inv(void* s, void* w) {
static void TouchMore_Take(void* s, void* w) {
Gui_Remove((struct Screen*)&TouchMoreScreen);
InventoryScreen_Show();
Game_ScreenshotRequested = true;
}
static void TouchMore_Menu(void* s, void* w) {
Gui_Remove((struct Screen*)&TouchMoreScreen);
@ -3587,7 +3588,7 @@ static const struct SimpleButtonDesc touchMore_btns[8] = {
{ -160, 0, "Speed", TouchMore_Speed },
{ -160, 50, "Fly", TouchMore_Fly },
{ -160, 100, "Menu", TouchMore_Menu },
{ 160, -50, "Inventory", TouchMore_Inv },
{ 160, -50, "Screenshot", TouchMore_Take },
{ 160, 0, "Fullscreen", TouchMore_Screen },
{ 160, 50, "Noclip", TouchMore_Noclip },
{ 160, 100, "Fog", TouchMore_Fog }

View File

@ -168,8 +168,9 @@ static void HUDScreen_ContextLost(void* screen) {
struct HUDScreen* s = (struct HUDScreen*)screen;
Font_Free(&s->font);
TextAtlas_Free(&s->posAtlas);
Elem_TryFree(&s->line1);
Elem_TryFree(&s->line2);
Elem_Free(&s->hotbar);
Elem_Free(&s->line1);
Elem_Free(&s->line2);
}
static void HUDScreen_ContextRecreated(void* screen) {
@ -179,32 +180,16 @@ static void HUDScreen_ContextRecreated(void* screen) {
struct HUDScreen* s = (struct HUDScreen*)screen;
struct TextWidget* line1 = &s->line1;
struct TextWidget* line2 = &s->line2;
int y;
Drawer2D_MakeFont(&s->font, 16, FONT_STYLE_NORMAL);
Font_ReducePadding(&s->font, 4);
y = 2;
TextWidget_Make(line1, ANCHOR_MIN, ANCHOR_MIN, 2, y);
HotbarWidget_SetFont(&s->hotbar, &s->font);
HUDScreen_Update(s, 1.0);
y += line1->height;
TextAtlas_Make(&s->posAtlas, &chars, &s->font, &prefix);
s->posAtlas.tex.Y = y;
y += s->posAtlas.tex.Height;
TextWidget_Make(line2, ANCHOR_MIN, ANCHOR_MIN, 2, 0);
/* We can't use y in TextWidget_Make because that DPI scales it */
line2->yOffset = y;
if (Game_ClassicMode) {
/* Swap around so 0.30 version is at top */
line2->yOffset = 2;
line1->yOffset = s->posAtlas.tex.Y;
TextWidget_SetConst(line2, "0.30", &s->font);
Widget_Layout(line1);
Widget_Layout(line2);
} else {
HUDScreen_UpdateHackState(s);
}
@ -214,7 +199,27 @@ static void HUDScreen_BuildMesh(void* screen) { }
static void HUDScreen_Layout(void* screen) {
struct HUDScreen* s = (struct HUDScreen*)screen;
struct TextWidget* line1 = &s->line1;
struct TextWidget* line2 = &s->line2;
int posY;
Widget_SetLocation(line1, ANCHOR_MIN, ANCHOR_MIN, 2, 2);
posY = line1->y + line1->height;
s->posAtlas.tex.Y = posY;
Widget_SetLocation(line2, ANCHOR_MIN, ANCHOR_MIN, 2, 0);
if (Game_ClassicMode) {
/* Swap around so 0.30 version is at top */
line2->yOffset = line1->yOffset;
line1->yOffset = posY;
Widget_Layout(line1);
} else {
/* We can't use y in TextWidget_Make because that DPI scales it */
line2->yOffset = posY + s->posAtlas.tex.Height;
}
Widget_Layout(&s->hotbar);
Widget_Layout(line2);
}
static int HUDScreen_KeyDown(void* screen, int key) {
@ -242,6 +247,8 @@ static int HUDscreen_PointerDown(void* screen, int id, int x, int y) {
static void HUDScreen_Init(void* screen) {
struct HUDScreen* s = (struct HUDScreen*)screen;
HotbarWidget_Create(&s->hotbar);
TextWidget_Init(&s->line1);
TextWidget_Init(&s->line2);
}
static void HUDScreen_Render(void* screen, double delta) {
@ -399,7 +406,8 @@ static void TabListOverlay_Layout(void* screen) {
minHeight = Display_ScaleY(300);
s->height = max(minHeight, height + s->title.height);
s->title.yOffset = s->y + paddingY / 2;
s->title.horAnchor = ANCHOR_CENTRE;
s->title.yOffset = s->y + paddingY / 2;
Widget_Layout(&s->title);
}
@ -682,7 +690,7 @@ static void TabListOverlay_Init(void* screen) {
s->active = true;
s->classic = Gui.ClassicTabList || !Server.SupportsExtPlayerList;
s->elementOffset = s->classic ? 0 : 10;
TextWidget_Make(&s->title, ANCHOR_CENTRE, ANCHOR_MIN, 0, 0);
TextWidget_Init(&s->title);
Event_Register_(&TabListEvents.Added, s, TabListOverlay_Add);
Event_Register_(&TabListEvents.Changed, s, TabListOverlay_Update);
@ -963,7 +971,7 @@ static void ChatScreen_DrawChat(struct ChatScreen* s, double delta) {
/* Destroy announcement texture before even rendering it at all, */
/* otherwise changing texture pack shows announcement for one frame */
if (s->announcement.tex.ID && now > Chat_AnnouncementReceived + 5) {
Elem_TryFree(&s->announcement);
Elem_Free(&s->announcement);
}
Elem_Render(&s->announcement, delta);
@ -985,17 +993,18 @@ static void ChatScreen_ContextLost(void* screen) {
struct ChatScreen* s = (struct ChatScreen*)screen;
ChatScreen_FreeChatFonts(s);
Elem_TryFree(&s->chat);
Elem_TryFree(&s->input.base);
Elem_TryFree(&s->altText);
Elem_TryFree(&s->status);
Elem_TryFree(&s->bottomRight);
Elem_TryFree(&s->clientStatus);
Elem_TryFree(&s->announcement);
Elem_Free(&s->chat);
Elem_Free(&s->input.base);
Elem_Free(&s->altText);
Elem_Free(&s->status);
Elem_Free(&s->bottomRight);
Elem_Free(&s->clientStatus);
Elem_Free(&s->announcement);
#ifdef CC_BUILD_TOUCH
Elem_TryFree(&s->send);
Elem_TryFree(&s->cancel);
if (!Input_TouchMode) return;
Elem_Free(&s->send);
Elem_Free(&s->cancel);
#endif
}
@ -1032,7 +1041,10 @@ static void ChatScreen_Layout(void* screen) {
Widget_SetLocation(&s->clientStatus, ANCHOR_MIN, ANCHOR_MAX, 10, 0);
ChatScreen_UpdateChatYOffsets(s);
Widget_SetLocation(&s->announcement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0);
s->announcement.yOffset = -WindowInfo.Height / 4;
Widget_Layout(&s->announcement);
#ifdef CC_BUILD_TOUCH
if (!Input_TouchMode) return;
Widget_SetLocation(&s->send, ANCHOR_MAX, ANCHOR_MIN, 10, 10);
@ -1191,7 +1203,7 @@ static void ChatScreen_Init(void* screen) {
s->chatTextures, ChatScreen_GetChat);
TextGroupWidget_Create(&s->clientStatus, CHAT_MAX_CLIENTSTATUS,
s->clientStatusTextures, ChatScreen_GetClientStatus);
TextWidget_Make(&s->announcement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 0);
TextWidget_Init(&s->announcement);
s->status.collapsible[0] = true; /* Texture pack download status */
s->clientStatus.collapsible[0] = true;
@ -1300,7 +1312,7 @@ static void InventoryScreen_OnBlockChanged(void* screen) {
static void InventoryScreen_ContextLost(void* screen) {
struct InventoryScreen* s = (struct InventoryScreen*)screen;
Font_Free(&s->font);
Elem_TryFree(&s->table);
Elem_Free(&s->table);
}
static void InventoryScreen_ContextRecreated(void* screen) {

View File

@ -64,11 +64,6 @@ static const struct WidgetVTABLE TextWidget_VTABLE = {
Widget_Pointer, Widget_Pointer, Widget_PointerMove,
TextWidget_BuildMesh, TextWidget_Render2
};
void TextWidget_Make(struct TextWidget* w, cc_uint8 horAnchor, cc_uint8 verAnchor, int xOffset, int yOffset) {
TextWidget_Init(w);
Widget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
}
void TextWidget_Init(struct TextWidget* w) {
Widget_Reset(w);
w->VTABLE = &TextWidget_VTABLE;
@ -256,30 +251,26 @@ void ButtonWidget_SetConst(struct ButtonWidget* w, const char* text, struct Font
/*########################################################################################################################*
*-----------------------------------------------------ScrollbarWidget-----------------------------------------------------*
*#########################################################################################################################*/
#define TABLE_MAX_ROWS_DISPLAYED 8
#define SCROLL_WIDTH 22
#define SCROLL_BORDER 2
#define SCROLL_NUBS_WIDTH 3
static PackedCol Scroll_BackCol = PackedCol_Make( 10, 10, 10, 220);
static PackedCol Scroll_BarCol = PackedCol_Make(100, 100, 100, 220);
static PackedCol Scroll_HoverCol = PackedCol_Make(122, 122, 122, 220);
#define SCROLL_BACK_COL PackedCol_Make( 10, 10, 10, 220)
#define SCROLL_BAR_COL PackedCol_Make(100, 100, 100, 220)
#define SCROLL_HOVER_COL PackedCol_Make(122, 122, 122, 220)
static void ScrollbarWidget_ClampTopRow(struct ScrollbarWidget* w) {
int maxTop = w->totalRows - TABLE_MAX_ROWS_DISPLAYED;
int maxTop = w->rowsTotal - w->rowsVisible;
if (w->topRow >= maxTop) w->topRow = maxTop;
if (w->topRow < 0) w->topRow = 0;
}
static float ScrollbarWidget_GetScale(struct ScrollbarWidget* w) {
float rows = (float)w->totalRows;
return (w->height - SCROLL_BORDER * 2) / rows;
float rows = (float)w->rowsTotal;
return (w->height - w->borderY * 2) / rows;
}
static void ScrollbarWidget_GetScrollbarCoords(struct ScrollbarWidget* w, int* y, int* height) {
float scale = ScrollbarWidget_GetScale(w);
*y = Math_Ceil(w->topRow * scale) + SCROLL_BORDER;
*height = Math_Ceil(TABLE_MAX_ROWS_DISPLAYED * scale);
*height = min(*y + *height, w->height - SCROLL_BORDER) - *y;
*y = Math_Ceil(w->topRow * scale) + w->borderY;
*height = Math_Ceil(w->rowsVisible * scale);
*height = min(*y + *height, w->height - w->borderY) - *y;
}
static void ScrollbarWidget_Render(void* widget, double delta) {
@ -289,23 +280,23 @@ static void ScrollbarWidget_Render(void* widget, double delta) {
cc_bool hovered;
x = w->x; width = w->width;
Gfx_Draw2DFlat(x, w->y, width, w->height, Scroll_BackCol);
Gfx_Draw2DFlat(x, w->y, width, w->height, SCROLL_BACK_COL);
ScrollbarWidget_GetScrollbarCoords(w, &y, &height);
x += SCROLL_BORDER; y += w->y;
width -= SCROLL_BORDER * 2;
x += w->borderX; y += w->y;
width -= w->borderX * 2;
hovered = Gui_ContainsPointers(x, y, width, height);
barCol = hovered ? Scroll_HoverCol : Scroll_BarCol;
barCol = hovered ? SCROLL_HOVER_COL : SCROLL_BAR_COL;
Gfx_Draw2DFlat(x, y, width, height, barCol);
if (height < 20) return;
x += SCROLL_NUBS_WIDTH; y += (height / 2);
width -= SCROLL_NUBS_WIDTH * 2;
x += w->nubsWidth; y += (height / 2);
width -= w->nubsWidth * 2;
Gfx_Draw2DFlat(x, y - 1 - 4, width, SCROLL_BORDER, Scroll_BackCol);
Gfx_Draw2DFlat(x, y - 1, width, SCROLL_BORDER, Scroll_BackCol);
Gfx_Draw2DFlat(x, y - 1 + 4, width, SCROLL_BORDER, Scroll_BackCol);
Gfx_Draw2DFlat(x, y + w->offsets[0], width, w->borderY, SCROLL_BACK_COL);
Gfx_Draw2DFlat(x, y + w->offsets[1], width, w->borderY, SCROLL_BACK_COL);
Gfx_Draw2DFlat(x, y + w->offsets[2], width, w->borderY, SCROLL_BACK_COL);
}
static int ScrollbarWidget_PointerDown(void* widget, int id, int x, int y) {
@ -321,9 +312,9 @@ static int ScrollbarWidget_PointerDown(void* widget, int id, int x, int y) {
ScrollbarWidget_GetScrollbarCoords(w, &posY, &height);
if (y < posY) {
w->topRow -= TABLE_MAX_ROWS_DISPLAYED;
w->topRow -= w->rowsVisible;
} else if (y >= posY + height) {
w->topRow += TABLE_MAX_ROWS_DISPLAYED;
w->topRow += w->rowsVisible;
} else {
w->draggingId = id;
w->dragOffset = y - posY;
@ -371,9 +362,18 @@ static const struct WidgetVTABLE ScrollbarWidget_VTABLE = {
};
void ScrollbarWidget_Create(struct ScrollbarWidget* w) {
Widget_Reset(w);
w->VTABLE = &ScrollbarWidget_VTABLE;
w->width = SCROLL_WIDTH;
w->totalRows = 0;
w->VTABLE = &ScrollbarWidget_VTABLE;
w->width = Display_ScaleX(22);
w->borderX = Display_ScaleX(2);
w->borderY = Display_ScaleY(2);
w->nubsWidth = Display_ScaleX(3);
w->offsets[0] = Display_ScaleY(-1 - 4);
w->offsets[1] = Display_ScaleY(-1);
w->offsets[2] = Display_ScaleY(-1 + 4);
w->rowsTotal = 0;
w->rowsVisible = 0;
w->topRow = 0;
w->scrollingAcc = 0.0f;
w->draggingId = 0;
@ -384,20 +384,18 @@ void ScrollbarWidget_Create(struct ScrollbarWidget* w) {
/*########################################################################################################################*
*------------------------------------------------------HotbarWidget-------------------------------------------------------*
*#########################################################################################################################*/
#define HotbarWidget_TileX(w, idx) (int)(w->x + w->slotXOffset + w->slotWidth * (idx))
static void HotbarWidget_RenderHotbarOutline(struct HotbarWidget* w) {
PackedCol white = PACKEDCOL_WHITE;
GfxResourceID tex;
float width;
int i, x;
int x;
tex = Gui.ClassicTexture ? Gui.GuiClassicTex : Gui.GuiTex;
w->backTex.ID = tex;
Texture_Render(&w->backTex);
i = Inventory.SelectedIndex;
width = w->slotWidth;
x = (int)(w->x + w->slotXOffset + width * i);
x = HotbarWidget_TileX(w, Inventory.SelectedIndex);
w->selTex.ID = tex;
w->selTex.X = (int)(x - w->selWidth / 2);
Gfx_Draw2DTexture(&w->selTex, white);
@ -406,16 +404,19 @@ static void HotbarWidget_RenderHotbarOutline(struct HotbarWidget* w) {
static void HotbarWidget_RenderHotbarBlocks(struct HotbarWidget* w) {
/* TODO: Should hotbar use its own VB? */
struct VertexTextured vertices[INVENTORY_BLOCKS_PER_HOTBAR * ISOMETRICDRAWER_MAXVERTICES];
float width, scale;
float scale;
int i, x, y;
IsometricDrawer_BeginBatch(vertices, Models.Vb);
width = w->slotWidth;
scale = w->elemSize / 2.0f;
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
x = (int)(w->x + w->slotXOffset + width * i);
x = HotbarWidget_TileX(w, i);
y = w->y + (w->height / 2);
#ifdef CC_BUILD_TOUCH
if (i == HOTBAR_MAX_INDEX && Input_TouchMode) continue;
#endif
IsometricDrawer_DrawBatch(Inventory_Get(i), scale, x, y);
}
IsometricDrawer_EndBatch();
@ -460,6 +461,13 @@ static void HotbarWidget_Render(void* widget, double delta) {
struct HotbarWidget* w = (struct HotbarWidget*)widget;
HotbarWidget_RenderHotbarOutline(w);
HotbarWidget_RenderHotbarBlocks(w);
#ifdef CC_BUILD_TOUCH
if (!Input_TouchMode) return;
w->ellipsisTex.X = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2;
w->ellipsisTex.Y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2;
Texture_Render(&w->ellipsisTex);
#endif
}
static int HotbarWidget_KeyDown(void* widget, int key) {
@ -510,11 +518,15 @@ static int HotbarWidget_PointerDown(void* widget, int id, int x, int y) {
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
cellX = (int)(w->x + width * i);
cellY = w->y;
if (!Gui_Contains(cellX, cellY, width, height, x, y)) continue;
if (Gui_Contains(cellX, cellY, width, height, x, y)) {
Inventory_SetSelectedIndex(i);
return true;
#ifdef CC_BUILD_TOUCH
if (i == HOTBAR_MAX_INDEX && Input_TouchMode) {
InventoryScreen_Show(); return true;
}
#endif
Inventory_SetSelectedIndex(i);
return true;
}
return false;
}
@ -535,8 +547,17 @@ static int HotbarWidget_MouseScroll(void* widget, float delta) {
return true;
}
static void HotbarWidget_Free(void* widget) {
#ifdef CC_BUILD_TOUCH
struct HotbarWidget* w = (struct HotbarWidget*)widget;
if (!Input_TouchMode) return;
Gfx_DeleteTexture(&w->ellipsisTex.ID);
#endif
}
static const struct WidgetVTABLE HotbarWidget_VTABLE = {
HotbarWidget_Render, Widget_NullFunc, HotbarWidget_Reposition,
HotbarWidget_Render, HotbarWidget_Free, HotbarWidget_Reposition,
HotbarWidget_KeyDown, HotbarWidget_KeyUp, HotbarWidget_MouseScroll,
HotbarWidget_PointerDown, Widget_Pointer, Widget_PointerMove
};
@ -547,17 +568,28 @@ void HotbarWidget_Create(struct HotbarWidget* w) {
w->verAnchor = ANCHOR_MAX;
}
void HotbarWidget_SetFont(struct HotbarWidget* w, struct FontDesc* font) {
#ifdef CC_BUILD_TOUCH
static const String dots = String_FromConst("...");
struct DrawTextArgs args;
if (!Input_TouchMode) return;
DrawTextArgs_Make(&args, &dots, font, true);
Drawer2D_MakeTextTexture(&w->ellipsisTex, &args);
#endif
}
/*########################################################################################################################*
*-------------------------------------------------------TableWidget-------------------------------------------------------*
*#########################################################################################################################*/
static int Table_X(struct TableWidget* w) { return w->x - 5 - 10; }
static int Table_Y(struct TableWidget* w) { return w->y - 5 - 30; }
static int Table_X(struct TableWidget* w) { return w->x - w->paddingX; }
static int Table_Y(struct TableWidget* w) { return w->y - w->paddingTopY; }
static int Table_Width(struct TableWidget* w) {
return w->blocksPerRow * w->cellSize + 10 + 20;
return w->blocksPerRow * w->cellSizeX + w->paddingX * 2;
}
static int Table_Height(struct TableWidget* w) {
return min(w->rowsCount, TABLE_MAX_ROWS_DISPLAYED) * w->cellSize + 10 + 40;
return w->rowsVisible * w->cellSizeY + w->paddingTopY + w->paddingMaxY;
}
#define TABLE_MAX_VERTICES (8 * 10 * ISOMETRICDRAWER_MAXVERTICES)
@ -567,9 +599,9 @@ static cc_bool TableWidget_GetCoords(struct TableWidget* w, int i, int* cellX, i
x = i % w->blocksPerRow;
y = i / w->blocksPerRow - w->scroll.topRow;
*cellX = w->x + w->cellSize * x;
*cellY = w->y + w->cellSize * y + 3;
return y >= 0 && y < TABLE_MAX_ROWS_DISPLAYED;
*cellX = w->x + w->cellSizeX * x;
*cellY = w->y + w->cellSizeY * y + 3;
return y >= 0 && y < w->rowsVisible;
}
static void TableWidget_MoveCursorToSelected(struct TableWidget* w) {
@ -579,7 +611,7 @@ static void TableWidget_MoveCursorToSelected(struct TableWidget* w) {
idx = w->selectedIndex;
TableWidget_GetCoords(w, idx, &x, &y);
x += w->cellSize / 2; y += w->cellSize / 2;
x += w->cellSizeX / 2; y += w->cellSizeY / 2;
Cursor_SetPosition(x, y);
}
@ -652,14 +684,14 @@ void TableWidget_RecreateBlocks(struct TableWidget* w) {
i++;
}
w->rowsCount = Math_CeilDiv(w->blocksCount, w->blocksPerRow);
w->rowsTotal = Math_CeilDiv(w->blocksCount, w->blocksPerRow);
Widget_Layout(w);
}
static void TableWidget_Render(void* widget, double delta) {
struct TableWidget* w = (struct TableWidget*)widget;
struct VertexTextured vertices[TABLE_MAX_VERTICES];
int cellSize, size;
int cellSizeX, cellSizeY, size;
float off;
int i, x, y;
@ -674,16 +706,18 @@ static void TableWidget_Render(void* widget, double delta) {
Gfx_Draw2DGradient(Table_X(w), Table_Y(w),
Table_Width(w), Table_Height(w), topBackCol, bottomBackCol);
if (w->rowsCount > TABLE_MAX_ROWS_DISPLAYED) {
if (w->rowsVisible < w->rowsTotal) {
Elem_Render(&w->scroll, delta);
}
cellSize = w->cellSize;
cellSizeX = w->cellSizeX;
cellSizeY = w->cellSizeY;
if (w->selectedIndex != -1 && Game_ClassicMode && w->blocks[w->selectedIndex] != BLOCK_AIR) {
TableWidget_GetCoords(w, w->selectedIndex, &x, &y);
off = cellSize * 0.1f;
size = (int)(cellSize + off * 2);
/* TODO: Need two size arguments, in case X/Y dpi differs */
off = cellSizeX * 0.1f;
size = (int)(cellSizeX + off * 2);
Gfx_Draw2DGradient((int)(x - off), (int)(y - off),
size, size, topSelCol, bottomSelCol);
}
@ -695,9 +729,10 @@ static void TableWidget_Render(void* widget, double delta) {
if (!TableWidget_GetCoords(w, i, &x, &y)) continue;
/* We want to always draw the selected block on top of others */
/* TODO: Need two size arguments, in case X/Y dpi differs */
if (i == w->selectedIndex) continue;
IsometricDrawer_DrawBatch(w->blocks[i], cellSize * 0.7f / 2.0f,
x + cellSize / 2, y + cellSize / 2);
IsometricDrawer_DrawBatch(w->blocks[i], cellSizeX * 0.7f / 2.0f,
x + cellSizeX / 2, y + cellSizeY / 2);
}
i = w->selectedIndex;
@ -705,8 +740,8 @@ static void TableWidget_Render(void* widget, double delta) {
TableWidget_GetCoords(w, i, &x, &y);
IsometricDrawer_DrawBatch(w->blocks[i],
(cellSize + w->selBlockExpand) * 0.7f / 2.0f,
x + cellSize / 2, y + cellSize / 2);
(cellSizeX + w->selBlockExpand) * 0.7f / 2.0f,
x + cellSizeX / 2, y + cellSizeY / 2);
}
IsometricDrawer_EndBatch();
@ -722,7 +757,7 @@ static void TableWidget_Free(void* widget) {
}
void TableWidget_Recreate(struct TableWidget* w) {
Elem_TryFree(w);
Elem_Free(w);
w->vb = Gfx_CreateDynamicVb(VERTEX_FORMAT_TEXTURED, TABLE_MAX_VERTICES);
TableWidget_RecreateDescTex(w);
}
@ -730,21 +765,31 @@ void TableWidget_Recreate(struct TableWidget* w) {
static void TableWidget_Reposition(void* widget) {
struct TableWidget* w = (struct TableWidget*)widget;
float scale = Gui_GetInventoryScale();
int rowsDisplayed;
int cellSize;
cellSize = (int)(50 * Math_SqrtF(scale));
w->cellSizeX = Display_ScaleX(cellSize);
w->cellSizeY = Display_ScaleY(cellSize);
w->cellSize = (int)(50 * Math_SqrtF(scale));
w->selBlockExpand = 25.0f * Math_SqrtF(scale);
rowsDisplayed = min(TABLE_MAX_ROWS_DISPLAYED, w->rowsCount);
w->rowsVisible = min(8, w->rowsTotal); /* 8 rows max */
w->width = w->cellSize * w->blocksPerRow;
w->height = w->cellSize * rowsDisplayed;
Widget_CalcPosition(w);
TableWidget_UpdateDescTexPos(w);
do {
w->width = w->cellSizeX * w->blocksPerRow;
w->height = w->cellSizeY * w->rowsVisible;
Widget_CalcPosition(w);
TableWidget_UpdateDescTexPos(w);
/* Does the table fit on screen? */
if (Game_ClassicMode || Table_Y(w) >= 0) break;
w->rowsVisible--;
} while (w->rowsVisible > 1);
w->scroll.x = Table_X(w) + Table_Width(w);
w->scroll.y = Table_Y(w);
w->scroll.height = Table_Height(w);
w->scroll.totalRows = w->rowsCount;
w->scroll.height = Table_Height(w);
w->scroll.rowsTotal = w->rowsTotal;
w->scroll.rowsVisible = w->rowsVisible;
}
static void TableWidget_ScrollRelative(struct TableWidget* w, int delta) {
@ -806,7 +851,7 @@ static int TableWidget_MouseScroll(void* widget, float delta) {
static int TableWidget_PointerMove(void* widget, int id, int x, int y) {
struct TableWidget* w = (struct TableWidget*)widget;
int cellSize, maxHeight;
int cellSizeX, cellSizeY, maxHeight;
int i, cellX, cellY;
if (Elem_HandlesPointerMove(&w->scroll, id, x, y)) return true;
@ -814,14 +859,15 @@ static int TableWidget_PointerMove(void* widget, int id, int x, int y) {
w->lastX = x; w->lastY = y;
w->selectedIndex = -1;
cellSize = w->cellSize;
maxHeight = cellSize * TABLE_MAX_ROWS_DISPLAYED;
cellSizeX = w->cellSizeX;
cellSizeY = w->cellSizeY;
maxHeight = cellSizeY * w->rowsVisible;
if (Gui_Contains(w->x, w->y + 3, w->width, maxHeight - 3 * 2, x, y)) {
for (i = 0; i < w->blocksCount; i++) {
TableWidget_GetCoords(w, i, &cellX, &cellY);
if (Gui_Contains(cellX, cellY, cellSize, cellSize, x, y)) {
if (Gui_Contains(cellX, cellY, cellSizeX, cellSizeY, x, y)) {
w->selectedIndex = i;
break;
}
@ -863,6 +909,10 @@ void TableWidget_Create(struct TableWidget* w) {
w->horAnchor = ANCHOR_CENTRE;
w->verAnchor = ANCHOR_CENTRE;
w->lastX = -20; w->lastY = -20;
w->paddingX = Display_ScaleX(15);
w->paddingTopY = Display_ScaleY(15 + 20);
w->paddingMaxY = Display_ScaleX(15);
}
void TableWidget_SetBlockTo(struct TableWidget* w, BlockID block) {
@ -876,7 +926,7 @@ void TableWidget_SetBlockTo(struct TableWidget* w, BlockID block) {
if (block == BLOCK_AIR) w->selectedIndex = -1;
w->scroll.topRow = w->selectedIndex / w->blocksPerRow;
w->scroll.topRow -= (TABLE_MAX_ROWS_DISPLAYED - 1);
w->scroll.topRow -= (w->rowsVisible - 1);
ScrollbarWidget_ClampTopRow(&w->scroll);
TableWidget_MoveCursorToSelected(w);
TableWidget_RecreateDescTex(w);

View File

@ -17,9 +17,6 @@ struct TextWidget {
};
#define TEXTWIDGET_MAX 4
/* Initialises a text widget. */
CC_NOINLINE void TextWidget_Make(struct TextWidget* w,
cc_uint8 horAnchor, cc_uint8 verAnchor, int xOffset, int yOffset);
/* Initialises a text widget. */
CC_NOINLINE void TextWidget_Init(struct TextWidget* w);
/* Draws the given text into a texture, then updates the position and size of this widget. */
@ -54,10 +51,12 @@ CC_NOINLINE void ButtonWidget_SetConst(struct ButtonWidget* w, const char* text,
/* Clickable and draggable scrollbar. */
struct ScrollbarWidget {
Widget_Body
int totalRows, topRow;
int topRow, rowsTotal, rowsVisible;
float scrollingAcc;
int dragOffset;
int draggingId;
int borderX, borderY;
int nubsWidth, offsets[3];
};
/* Resets state of the given scrollbar widget to default. */
CC_NOINLINE void ScrollbarWidget_Create(struct ScrollbarWidget* w);
@ -70,18 +69,20 @@ struct HotbarWidget {
float slotXOffset, elemSize;
float scrollAcc;
cc_bool altHandled;
struct Texture ellipsisTex;
};
/* Resets state of the given hotbar widget to default. */
CC_NOINLINE void HotbarWidget_Create(struct HotbarWidget* w);
CC_NOINLINE void HotbarWidget_SetFont(struct HotbarWidget* w, struct FontDesc* font);
/* A table of blocks. */
struct TableWidget {
Widget_Body
int blocksCount, blocksPerRow, rowsCount;
int blocksCount, blocksPerRow;
int rowsTotal, rowsVisible;
int lastCreatedIndex;
struct FontDesc* font;
int selectedIndex, cellSize;
int selectedIndex, cellSizeX, cellSizeY;
float selBlockExpand;
GfxResourceID vb;
cc_bool pendingClose;
@ -89,7 +90,8 @@ struct TableWidget {
BlockID blocks[BLOCK_COUNT];
struct ScrollbarWidget scroll;
struct Texture descTex;
int lastX, lastY;
int lastX, lastY, paddingX;
int paddingTopY, paddingMaxY;
};
CC_NOINLINE void TableWidget_Create(struct TableWidget* w);