mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 18:45:23 -04:00
Fix scroll position in chat and chat input caret getting reset on window resize by separating out init/contextrecreated
This commit is contained in:
parent
60565346fa
commit
b6d9b9b88d
102
src/Screens.c
102
src/Screens.c
@ -646,10 +646,6 @@ void GeneratingScreen_Show(void) {
|
||||
static struct HUDScreen HUDScreen_Instance;
|
||||
#define CH_EXTENT 16
|
||||
|
||||
/* needed for lost contexts, to restore chat typed in */
|
||||
static char chatInputBuffer[INPUTWIDGET_MAX_LINES * INPUTWIDGET_LEN];
|
||||
static String chatInputStr = String_FromArray(chatInputBuffer);
|
||||
|
||||
static int HUDScreen_BottomOffset(void) { return HUDScreen_Instance.hotbar.height; }
|
||||
static int HUDScreen_InputUsedHeight(struct HUDScreen* s) {
|
||||
if (s->altText.height == 0) {
|
||||
@ -698,50 +694,53 @@ static void HUDScreen_InitChatFonts(struct HUDScreen* s) {
|
||||
Drawer2D_MakeFont(&s->announcementFont, size, FONT_STYLE_NORMAL);
|
||||
}
|
||||
|
||||
static void HUDScreen_ConstructWidgets(struct HUDScreen* s) {
|
||||
int yOffset = HUDScreen_BottomOffset() + 15;
|
||||
ChatInputWidget_Create(&s->input, &s->chatFont);
|
||||
Widget_SetLocation(&s->input.base, ANCHOR_MIN, ANCHOR_MAX, 5, 5);
|
||||
static void HUDScreen_ChatUpdateFont(struct HUDScreen* s) {
|
||||
ChatInputWidget_SetFont(&s->input, &s->chatFont);
|
||||
TextGroupWidget_SetFont(&s->status, &s->chatFont);
|
||||
TextGroupWidget_SetFont(&s->bottomRight, &s->chatFont);
|
||||
TextGroupWidget_SetFont(&s->chat, &s->chatFont);
|
||||
TextGroupWidget_SetFont(&s->clientStatus, &s->chatFont);
|
||||
}
|
||||
|
||||
SpecialInputWidget_Create(&s->altText, &s->chatFont, &s->input.base);
|
||||
Elem_Init(&s->altText);
|
||||
static void HUDScreen_ChatUpdateLayout(struct HUDScreen* s) {
|
||||
int yOffset = HUDScreen_BottomOffset() + 15;
|
||||
Widget_SetLocation(&s->input.base, ANCHOR_MIN, ANCHOR_MAX, 5, 5);
|
||||
HUDScreen_UpdateAltTextY(s);
|
||||
|
||||
Widget_SetLocation(&s->status, ANCHOR_MAX, ANCHOR_MIN, 0, 0);
|
||||
Widget_SetLocation(&s->bottomRight, ANCHOR_MAX, ANCHOR_MAX, 0, yOffset);
|
||||
Widget_SetLocation(&s->chat, ANCHOR_MIN, ANCHOR_MAX, 10, yOffset);
|
||||
Widget_SetLocation(&s->clientStatus, ANCHOR_MIN, ANCHOR_MAX, 10, yOffset);
|
||||
}
|
||||
|
||||
static void HUDScreen_ChatInit(struct HUDScreen* s) {
|
||||
ChatInputWidget_Create(&s->input);
|
||||
SpecialInputWidget_Create(&s->altText, &s->chatFont, &s->input.base);
|
||||
|
||||
TextGroupWidget_Create(&s->status, CHAT_MAX_STATUS,
|
||||
s->statusTextures, HUDScreen_GetStatus);
|
||||
Widget_SetLocation(&s->status, ANCHOR_MAX, ANCHOR_MIN, 0, 0);
|
||||
s->status.placeholderHeight[0] = false; /* Texture pack download status */
|
||||
TextGroupWidget_SetFont(&s->status, &s->chatFont);
|
||||
|
||||
TextGroupWidget_Create(&s->bottomRight, CHAT_MAX_BOTTOMRIGHT,
|
||||
s->bottomRightTextures, HUDScreen_GetBottomRight);
|
||||
Widget_SetLocation(&s->bottomRight, ANCHOR_MAX, ANCHOR_MAX, 0, yOffset);
|
||||
TextGroupWidget_SetFont(&s->bottomRight, &s->chatFont);
|
||||
|
||||
TextGroupWidget_Create(&s->chat, Gui_Chatlines,
|
||||
s->chatTextures, HUDScreen_GetChat);
|
||||
s->chat.underlineUrls = !Game_ClassicMode;
|
||||
Widget_SetLocation(&s->chat, ANCHOR_MIN, ANCHOR_MAX, 10, yOffset);
|
||||
TextGroupWidget_SetFont(&s->chat, &s->chatFont);
|
||||
|
||||
TextGroupWidget_Create(&s->clientStatus, CHAT_MAX_CLIENTSTATUS,
|
||||
s->clientStatusTextures, HUDScreen_GetClientStatus);
|
||||
Widget_SetLocation(&s->clientStatus, ANCHOR_MIN, ANCHOR_MAX, 10, yOffset);
|
||||
TextGroupWidget_SetFont(&s->clientStatus, &s->chatFont);
|
||||
|
||||
TextWidget_Make(&s->announcement, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -Window_Height / 4);
|
||||
|
||||
s->status.placeholderHeight[0] = false; /* Texture pack download status */
|
||||
s->chat.underlineUrls = !Game_ClassicMode;
|
||||
s->chatIndex = Chat_Log.count - Gui_Chatlines;
|
||||
}
|
||||
|
||||
static void HUDScreen_SetInitialMessages(struct HUDScreen* s) {
|
||||
s->chatIndex = Chat_Log.count - Gui_Chatlines;
|
||||
static void HUDScreen_Redraw(struct HUDScreen* s) {
|
||||
TextGroupWidget_RedrawAll(&s->chat);
|
||||
TextWidget_Set(&s->announcement, &Chat_Announcement, &s->announcementFont);
|
||||
|
||||
TextGroupWidget_RedrawAll(&s->status);
|
||||
TextGroupWidget_RedrawAll(&s->bottomRight);
|
||||
TextGroupWidget_RedrawAll(&s->clientStatus);
|
||||
|
||||
if (s->grabsInput) HUDScreen_OpenInput(&chatInputStr);
|
||||
if (s->grabsInput) InputWidget_UpdateText(&s->input.base);
|
||||
SpecialInputWidget_Redraw(&s->altText);
|
||||
}
|
||||
|
||||
static void HUDScreen_UpdateChatYOffset(struct HUDScreen* s, bool force) {
|
||||
@ -787,9 +786,7 @@ static void HUDScreen_EnterChatInput(struct HUDScreen* s, bool close) {
|
||||
|
||||
s->grabsInput = false;
|
||||
Camera_CheckFocus();
|
||||
|
||||
if (close) InputWidget_Clear(&s->input.base);
|
||||
chatInputStr.length = 0;
|
||||
|
||||
input = &s->input.base;
|
||||
input->OnPressedEnter(input);
|
||||
@ -958,12 +955,6 @@ static void HUDScreen_ContextLost(void* screen) {
|
||||
Font_Free(&s->playerFont);
|
||||
HUDScreen_FreeChatFonts(s);
|
||||
|
||||
if (s->grabsInput) {
|
||||
String_Copy(&chatInputStr, &s->input.base.text);
|
||||
/* TODO: Why are we checking camera here */
|
||||
Camera_CheckFocus();
|
||||
}
|
||||
|
||||
Elem_TryFree(&s->chat);
|
||||
Elem_TryFree(&s->input.base);
|
||||
Elem_TryFree(&s->altText);
|
||||
@ -977,22 +968,9 @@ static void HUDScreen_ContextLost(void* screen) {
|
||||
s->showingList = false;
|
||||
}
|
||||
|
||||
static void HUDScreen_ContextRecreated(void* screen) {
|
||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||
int size;
|
||||
bool extended;
|
||||
Widget_Reposition(&s->hotbar);
|
||||
|
||||
size = Drawer2D_BitmappedText ? 16 : 11;
|
||||
Drawer2D_MakeFont(&s->playerFont, size, FONT_STYLE_NORMAL);
|
||||
HUDScreen_InitChatFonts(s);
|
||||
|
||||
HUDScreen_ConstructWidgets(s);
|
||||
HUDScreen_SetInitialMessages(s);
|
||||
HUDScreen_UpdateChatYOffset(s, true);
|
||||
|
||||
static void HUDScreen_RemakePlayerList(struct HUDScreen* s) {
|
||||
bool extended = Server.SupportsExtPlayerList && !Gui_ClassicTabList;
|
||||
if (!s->wasShowingList) return;
|
||||
extended = Server.SupportsExtPlayerList && !Gui_ClassicTabList;
|
||||
PlayerListWidget_Create(&s->playerList, &s->playerFont, !extended);
|
||||
s->showingList = true;
|
||||
|
||||
@ -1000,13 +978,22 @@ static void HUDScreen_ContextRecreated(void* screen) {
|
||||
Widget_Reposition(&s->playerList);
|
||||
}
|
||||
|
||||
static void HUDScreen_ContextRecreated(void* screen) {
|
||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||
int size = Drawer2D_BitmappedText ? 16 : 11;
|
||||
Drawer2D_MakeFont(&s->playerFont, size, FONT_STYLE_NORMAL);
|
||||
HUDScreen_InitChatFonts(s);
|
||||
HUDScreen_ChatUpdateFont(s);
|
||||
|
||||
HUDScreen_Redraw(s);
|
||||
HUDScreen_UpdateChatYOffset(s, true);
|
||||
HUDScreen_RemakePlayerList(s);
|
||||
Widget_Reposition(&s->hotbar);
|
||||
}
|
||||
|
||||
static void HUDScreen_OnResize(void* screen) {
|
||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||
/* TODO: Kill this awful hack with fire */
|
||||
bool active = s->altText.active;
|
||||
Elem_Free(s); Elem_Init(s);
|
||||
SpecialInputWidget_SetActive(&s->altText, active);
|
||||
|
||||
HUDScreen_ChatUpdateLayout(s);
|
||||
Widget_Reposition(&s->hotbar);
|
||||
if (s->showingList) { Widget_Reposition(&s->playerList); }
|
||||
}
|
||||
@ -1034,7 +1021,7 @@ static bool HUDScreen_KeyDown(void* screen, Key key) {
|
||||
if (key == playerListKey && handlesList) {
|
||||
if (!s->showingList && !Server.IsSinglePlayer) {
|
||||
s->wasShowingList = true;
|
||||
HUDScreen_ContextRecreated(s);
|
||||
HUDScreen_RemakePlayerList(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1157,6 +1144,7 @@ static void HUDScreen_Init(void* screen) {
|
||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||
s->wasShowingList = false;
|
||||
HotbarWidget_Create(&s->hotbar);
|
||||
HUDScreen_ChatInit(s);
|
||||
|
||||
Event_RegisterChat(&ChatEvents.ChatReceived, s, HUDScreen_ChatReceived);
|
||||
Event_RegisterInt(&ChatEvents.ColCodeChanged, s, HUDScreen_ColCodeChanged);
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
#define Widget_UV(u1,v1, u2,v2) Tex_UV(u1/256.0f,v1/256.0f, u2/256.0f,v2/256.0f)
|
||||
static void Widget_NullFunc(void* widget) { }
|
||||
static Size2D Size2D_Empty;
|
||||
|
||||
static bool Widget_Mouse(void* elem, int x, int y, MouseButton btn) { return false; }
|
||||
static bool Widget_Key(void* elem, Key key) { return false; }
|
||||
static bool Widget_MouseMove(void* elem, int x, int y) { return false; }
|
||||
@ -1711,27 +1709,28 @@ static const struct WidgetVTABLE ChatInputWidget_VTABLE = {
|
||||
InputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll,
|
||||
InputWidget_Reposition
|
||||
};
|
||||
void ChatInputWidget_Create(struct ChatInputWidget* w, FontDesc* font) {
|
||||
struct DrawTextArgs args;
|
||||
void ChatInputWidget_Create(struct ChatInputWidget* w) {
|
||||
Widget_Reset(w);
|
||||
w->typingLogPos = Chat_InputLog.count; /* Index of newest entry + 1. */
|
||||
w->base.VTABLE = &ChatInputWidget_VTABLE;
|
||||
w->base.font = font;
|
||||
w->typingLogPos = Chat_InputLog.count; /* Index of newest entry + 1. */
|
||||
w->base.VTABLE = &ChatInputWidget_VTABLE;
|
||||
w->base.caretPos = -1;
|
||||
|
||||
w->base.convertPercents = !Game_ClassicMode;
|
||||
w->base.showCaret = true;
|
||||
w->base.padding = 5;
|
||||
w->base.lineHeight = Drawer2D_FontHeight(font, true);
|
||||
|
||||
w->base.GetMaxLines = ChatInputWidget_GetMaxLines;
|
||||
w->base.RemakeTexture = ChatInputWidget_RemakeTexture;
|
||||
w->base.OnPressedEnter = ChatInputWidget_OnPressedEnter;
|
||||
w->base.AllowedChar = InputWidget_AllowedChar;
|
||||
w->base.GetMaxLines = ChatInputWidget_GetMaxLines;
|
||||
w->base.RemakeTexture = ChatInputWidget_RemakeTexture;
|
||||
w->base.OnPressedEnter = ChatInputWidget_OnPressedEnter;
|
||||
w->base.AllowedChar = InputWidget_AllowedChar;
|
||||
|
||||
String_InitArray(w->base.text, w->_textBuffer);
|
||||
String_InitArray(w->origStr, w->_origBuffer);
|
||||
}
|
||||
|
||||
void ChatInputWidget_SetFont(struct ChatInputWidget* w, FontDesc* font) {
|
||||
struct DrawTextArgs args;
|
||||
w->base.font = font;
|
||||
w->base.lineHeight = Drawer2D_FontHeight(font, true);
|
||||
DrawTextArgs_Make(&args, &chatInputPrefix, font, true);
|
||||
w->base.prefixWidth = Drawer2D_TextWidth(&args);
|
||||
}
|
||||
@ -2577,7 +2576,8 @@ static void SpecialInputWidget_IntersectsBody(struct SpecialInputWidget* w, int
|
||||
|
||||
static void SpecialInputTab_Init(struct SpecialInputTab* tab, STRING_REF String* title, int itemsPerRow, int charsPerItem, STRING_REF String* contents) {
|
||||
tab->title = *title;
|
||||
tab->titleSize = Size2D_Empty;
|
||||
tab->titleSize.Width = 0;
|
||||
tab->titleSize.Height = 0;
|
||||
tab->contents = *contents;
|
||||
tab->itemsPerRow = itemsPerRow;
|
||||
tab->charsPerItem = charsPerItem;
|
||||
@ -2707,22 +2707,13 @@ static void SpecialInputWidget_Make(struct SpecialInputWidget* w, struct Special
|
||||
Mem_Free(bmp.Scan0);
|
||||
}
|
||||
|
||||
static void SpecialInputWidget_Redraw(struct SpecialInputWidget* w) {
|
||||
void SpecialInputWidget_Redraw(struct SpecialInputWidget* w) {
|
||||
SpecialInputWidget_Make(w, &w->tabs[w->selectedIndex]);
|
||||
w->width = w->tex.Width;
|
||||
w->height = w->tex.Height;
|
||||
w->height = w->active ? w->tex.Height : 0;
|
||||
w->pendingRedraw = false;
|
||||
}
|
||||
|
||||
static void SpecialInputWidget_Init(void* widget) {
|
||||
struct SpecialInputWidget* w = (struct SpecialInputWidget*)widget;
|
||||
w->x = 5; w->y = 5;
|
||||
|
||||
SpecialInputWidget_InitTabs(w);
|
||||
SpecialInputWidget_Redraw(w);
|
||||
SpecialInputWidget_SetActive(w, w->active);
|
||||
}
|
||||
|
||||
static void SpecialInputWidget_Render(void* widget, double delta) {
|
||||
struct SpecialInputWidget* w = (struct SpecialInputWidget*)widget;
|
||||
Texture_Render(&w->tex);
|
||||
@ -2762,7 +2753,7 @@ void SpecialInputWidget_SetActive(struct SpecialInputWidget* w, bool active) {
|
||||
}
|
||||
|
||||
static const struct WidgetVTABLE SpecialInputWidget_VTABLE = {
|
||||
SpecialInputWidget_Init, SpecialInputWidget_Render, SpecialInputWidget_Free,
|
||||
Widget_NullFunc, SpecialInputWidget_Render, SpecialInputWidget_Free,
|
||||
Widget_Key, Widget_Key,
|
||||
SpecialInputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll,
|
||||
Widget_CalcPosition
|
||||
@ -2772,5 +2763,7 @@ void SpecialInputWidget_Create(struct SpecialInputWidget* w, FontDesc* font, str
|
||||
w->VTABLE = &SpecialInputWidget_VTABLE;
|
||||
w->verAnchor = ANCHOR_MAX;
|
||||
w->font = font;
|
||||
w->target = target;
|
||||
w->target = target;
|
||||
SpecialInputWidget_InitTabs(w);
|
||||
w->x = 5; w->y = 5;
|
||||
}
|
||||
|
@ -190,7 +190,8 @@ struct ChatInputWidget {
|
||||
char _origBuffer[INPUTWIDGET_MAX_LINES * INPUTWIDGET_LEN];
|
||||
};
|
||||
|
||||
CC_NOINLINE void ChatInputWidget_Create(struct ChatInputWidget* w, FontDesc* font);
|
||||
CC_NOINLINE void ChatInputWidget_Create(struct ChatInputWidget* w);
|
||||
CC_NOINLINE void ChatInputWidget_SetFont(struct ChatInputWidget* w, FontDesc* font);
|
||||
|
||||
|
||||
/* Retrieves the text for the i'th line in the group */
|
||||
@ -269,6 +270,7 @@ struct SpecialInputWidget {
|
||||
};
|
||||
|
||||
CC_NOINLINE void SpecialInputWidget_Create(struct SpecialInputWidget* w, FontDesc* font, struct InputWidget* target);
|
||||
CC_NOINLINE void SpecialInputWidget_Redraw(struct SpecialInputWidget* w);
|
||||
CC_NOINLINE void SpecialInputWidget_UpdateCols(struct SpecialInputWidget* w);
|
||||
CC_NOINLINE void SpecialInputWidget_SetActive(struct SpecialInputWidget* w, bool active);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user