mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Merge pull request #724 from UnknownShadow200/MobileInv
Improve inventory (especially for mobile)
This commit is contained in:
commit
fe44fb336d
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
13
src/Menus.c
13
src/Menus.c
@ -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 }
|
||||
|
@ -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) {
|
||||
|
206
src/Widgets.c
206
src/Widgets.c
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user