diff --git a/src/Menus.c b/src/Menus.c index c306af9d9..e1e0227ad 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -61,6 +61,7 @@ static void Menu_OldInput(void* s, int i, struct MenuInputWidget* input, int wid MenuInputWidget_Create(input, width, 30, text, font, desc); Widget_SetLocation(input, horAnchor, verAnchor, x, y); input->base.showCaret = true; + InputWidget_UpdateText(&input->base); ((struct Screen*)s)->widgets[i] = (struct Widget*)input; } @@ -864,35 +865,29 @@ static bool EditHotkeyScreen_KeyDown(void* screen, Key key) { } static void EditHotkeyScreen_ContextRecreated(void* screen) { - struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; - struct MenuInputDesc desc; - String text; bool existed; - - MenuInput_String(desc); - existed = s->origHotkey.Trigger != KEY_NONE; - if (existed) { - text = StringsBuffer_UNSAFE_Get(&HotkeysText, s->origHotkey.TextIndex); - } else { text = String_Empty; } + struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; + bool existed = s->origHotkey.Trigger != KEY_NONE; EditHotkeyScreen_UpdateBaseKey(s); EditHotkeyScreen_UpdateModifiers(s); EditHotkeyScreen_UpdateLeaveOpen(s); ButtonWidget_SetConst(&s->buttons[3], existed ? "Save changes" : "Add hotkey", &s->titleFont); - ButtonWidget_SetConst(&s->buttons[4], existed ? "Remove hotkey" : "Cancel", &s->titleFont); - + ButtonWidget_SetConst(&s->buttons[4], existed ? "Remove hotkey" : "Cancel", &s->titleFont); + InputWidget_UpdateText(&s->input.base); ButtonWidget_SetConst(&s->cancel, "Cancel", &s->titleFont); - Menu_OldInput(s, 6, &s->input, 500, &text, &s->textFont, &desc, - ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35); } static void EditHotkeyScreen_Init(void* screen) { static struct Widget* widgets[7]; struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; + struct MenuInputDesc desc; + String text; s->widgets = widgets; s->numWidgets = Array_Elems(widgets); s->selectedI = -1; MenuScreen_Init(screen); + MenuInput_String(desc); EditHotkeyScreen_Make(s, 0, 0, -150, EditHotkeyScreen_BaseKey); EditHotkeyScreen_Make(s, 1, 0, -100, EditHotkeyScreen_Modifiers); @@ -900,7 +895,13 @@ static void EditHotkeyScreen_Init(void* screen) { EditHotkeyScreen_Make(s, 3, 0, 80, EditHotkeyScreen_SaveChanges); EditHotkeyScreen_Make(s, 4, 0, 130, EditHotkeyScreen_RemoveHotkey); - Menu_Back(s, 5, &s->cancel, Menu_SwitchHotkeys); + if (s->origHotkey.Trigger) { + text = StringsBuffer_UNSAFE_Get(&HotkeysText, s->origHotkey.TextIndex); + } else { text = String_Empty; } + + Menu_Input(s, 6, &s->input, 500, &text, &s->textFont, &desc, + ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35); + Menu_Back(s, 5, &s->cancel, Menu_SwitchHotkeys); } static struct ScreenVTABLE EditHotkeyScreen_VTABLE = { @@ -990,12 +991,12 @@ static void GenLevelScreen_InputClick(void* screen, void* input) { s->selected->base.showCaret = true; } -static void GenLevelScreen_Input(struct GenLevelScreen* s, int i, int y, bool seed, int def) { +static void GenLevelScreen_Make(struct GenLevelScreen* s, int i, int y, int def) { String tmp; char tmpBuffer[STRING_SIZE]; - struct MenuInputWidget* input = &s->inputs[i]; struct MenuInputDesc desc; + PackedCol col = PACKEDCOL_CONST(224, 224, 224, 255); - if (seed) { + if (i == 3) { MenuInput_Seed(desc); } else { MenuInput_Int(desc, 1, 8192, def); @@ -1004,16 +1005,13 @@ static void GenLevelScreen_Input(struct GenLevelScreen* s, int i, int y, bool se String_InitArray(tmp, tmpBuffer); desc.VTABLE->GetDefault(&desc, &tmp); - Menu_OldInput(s, i, input, 200, &tmp, &s->textFont, &desc, + Menu_Input(s, i, &s->inputs[i], 200, &tmp, &s->textFont, &desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, y); + s->inputs[i].base.showCaret = false; + s->inputs[i].base.MenuClick = GenLevelScreen_InputClick; - input->base.showCaret = false; - input->base.MenuClick = GenLevelScreen_InputClick; -} - -static void GenLevelScreen_Label(struct GenLevelScreen* s, int i, int y) { - PackedCol col = PACKEDCOL_CONST(224, 224, 224, 255); - Menu_Label(s, i + 4, &s->labels[i], ANCHOR_CENTRE_MAX, ANCHOR_CENTRE, 110, y); + Menu_Label(s, i + 4, &s->labels[i], + ANCHOR_CENTRE_MAX, ANCHOR_CENTRE, 110, y); s->labels[i].col = col; } @@ -1032,14 +1030,14 @@ static bool GenLevelScreen_KeyPress(void* screen, char keyChar) { static void GenLevelScreen_ContextRecreated(void* screen) { struct GenLevelScreen* s = (struct GenLevelScreen*)screen; - GenLevelScreen_Input(s, 0, -80, false, World.Width); - GenLevelScreen_Input(s, 1, -40, false, World.Height); - GenLevelScreen_Input(s, 2, 0, false, World.Length); - GenLevelScreen_Input(s, 3, 40, true, 0); + InputWidget_UpdateText(&s->inputs[0].base); + InputWidget_UpdateText(&s->inputs[1].base); + InputWidget_UpdateText(&s->inputs[2].base); + InputWidget_UpdateText(&s->inputs[3].base); TextWidget_SetConst(&s->labels[0], "Width:", &s->textFont); TextWidget_SetConst(&s->labels[1], "Height:", &s->textFont); - TextWidget_SetConst(&s->labels[2], "Length:", &s->textFont);; + TextWidget_SetConst(&s->labels[2], "Length:", &s->textFont); TextWidget_SetConst(&s->labels[3], "Seed:", &s->textFont); TextWidget_SetConst(&s->title, "Generate new level", &s->textFont); @@ -1056,10 +1054,10 @@ static void GenLevelScreen_Init(void* screen) { s->widgets = widgets; s->numWidgets = Array_Elems(widgets); - GenLevelScreen_Label(s, 0, -80); - GenLevelScreen_Label(s, 1, -40); - GenLevelScreen_Label(s, 2, 0); - GenLevelScreen_Label(s, 3, 40); + GenLevelScreen_Make(s, 0, -80, World.Width); + GenLevelScreen_Make(s, 1, -40, World.Height); + GenLevelScreen_Make(s, 2, 0, World.Length); + GenLevelScreen_Make(s, 3, 40, 0); Menu_Label(s, 8, &s->title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -130); @@ -1262,25 +1260,22 @@ static bool SaveLevelScreen_KeyDown(void* screen, Key key) { static void SaveLevelScreen_ContextRecreated(void* screen) { struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; - struct MenuInputDesc desc; - MenuInput_Path(desc); - SaveLevelScreen_UpdateSave(s); SaveLevelScreen_UpdateSchem(s); TextWidget_SetConst(&s->mcEdit, "&eCan be imported into MCEdit", &s->textFont); + InputWidget_UpdateText(&s->input.base); ButtonWidget_SetConst(&s->cancel, "Cancel", &s->titleFont); - - Menu_OldInput(s, 4, &s->input, 500, &String_Empty, &s->textFont, &desc, - ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30); } static void SaveLevelScreen_Init(void* screen) { static struct Widget* widgets[6]; struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; + struct MenuInputDesc desc; s->widgets = widgets; s->numWidgets = Array_Elems(widgets); MenuScreen_Init(s); + MenuInput_Path(desc); Menu_Button(s, 0, &s->save, 300, SaveLevelScreen_Classic, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 20); @@ -1289,6 +1284,8 @@ static void SaveLevelScreen_Init(void* screen) { Menu_Label(s, 2, &s->mcEdit, ANCHOR_CENTRE, ANCHOR_CENTRE, 110, 120); Menu_Back(s, 3, &s->cancel, Menu_SwitchPause); + Menu_Input(s, 4, &s->input, 500, &String_Empty, &s->textFont, &desc, + ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30); Menu_Label(s, 5, &s->desc, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 65); } diff --git a/src/Widgets.c b/src/Widgets.c index c2362b806..681f342f5 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -906,11 +906,18 @@ static char InputWidget_GetLastCol(struct InputWidget* w, int x, int y) { } static void InputWidget_UpdateCaret(struct InputWidget* w) { + static const String caret = String_FromConst("_"); BitmapCol col; String line; char lineBuffer[STRING_SIZE]; struct DrawTextArgs args; int maxChars, lineWidth; char colCode; + + if (!w->caretTex.ID) { + DrawTextArgs_Make(&args, &caret, w->font, true); + Drawer2D_MakeTextTexture(&w->caretTex, &args, 0, 0); + w->caretWidth = (uint16_t)((w->caretTex.Width * 3) / 4); + } maxChars = w->GetMaxLines() * INPUTWIDGET_LEN; if (w->caretPos >= maxChars) w->caretPos = -1; @@ -1142,16 +1149,15 @@ static bool InputWidget_OtherKey(struct InputWidget* w, Key key) { return false; } -static void InputWidget_Init(void* widget) { - struct InputWidget* w = (struct InputWidget*)widget; +void InputWidget_UpdateText(struct InputWidget* w) { int lines = w->GetMaxLines(); - if (lines > 1) { WordWrap_Do(&w->text, w->lines, lines, INPUTWIDGET_LEN); } else { w->lines[0] = w->text; } + Gfx_DeleteTexture(&w->inputTex.ID); InputWidget_CalculateLineSizes(w); w->RemakeTexture(w); InputWidget_UpdateCaret(w); @@ -1163,11 +1169,6 @@ static void InputWidget_Free(void* widget) { Gfx_DeleteTexture(&w->caretTex.ID); } -void InputWidget_UpdateText(struct InputWidget* w) { - Gfx_DeleteTexture(&w->inputTex.ID); - InputWidget_Init(w); -} - static void InputWidget_Reposition(void* widget) { struct InputWidget* w = (struct InputWidget*)widget; int oldX = w->x, oldY = w->y; @@ -1240,31 +1241,6 @@ static bool InputWidget_MouseDown(void* widget, int x, int y, MouseButton button return true; } -CC_NOINLINE static void InputWidget_Create(struct InputWidget* w, FontDesc* font, STRING_REF const String* prefix) { - static const String caret = String_FromConst("_"); - struct DrawTextArgs args; - Size2D size; - Widget_Reset(w); - - w->font = font; - w->prefix = *prefix; - w->caretPos = -1; - w->OnPressedEnter = InputWidget_OnPressedEnter; - w->AllowedChar = InputWidget_AllowedChar; - - DrawTextArgs_Make(&args, &caret, font, true); - Gfx_DeleteTexture(&w->caretTex.ID); /* TODO: AWFUL HACK */ - Drawer2D_MakeTextTexture(&w->caretTex, &args, 0, 0); - w->caretTex.Width = (uint16_t)((w->caretTex.Width * 3) / 4); - w->caretWidth = w->caretTex.Width; - - if (!prefix->length) return; - DrawTextArgs_Make(&args, prefix, font, true); - size = Drawer2D_MeasureText(&args); - w->prefixWidth = size.Width; w->width = size.Width; - w->height = w->lineHeight; -} - /*########################################################################################################################* *-----------------------------------------------------MenuInputDesc-------------------------------------------------------* @@ -1471,14 +1447,16 @@ static bool MenuInputWidget_AllowedChar(void* widget, char c) { static int MenuInputWidget_GetMaxLines(void) { return 1; } static struct WidgetVTABLE MenuInputWidget_VTABLE = { - InputWidget_Init, MenuInputWidget_Render, InputWidget_Free, + Widget_NullFunc, MenuInputWidget_Render, InputWidget_Free, InputWidget_KeyDown, InputWidget_KeyUp, InputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll, InputWidget_Reposition }; void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, const String* text, FontDesc* font, struct MenuInputDesc* desc) { - InputWidget_Create(&w->base, font, &String_Empty); - w->base.VTABLE = &MenuInputWidget_VTABLE; + Widget_Reset(w); + w->base.VTABLE = &MenuInputWidget_VTABLE; + w->base.font = font; + w->base.caretPos = -1; w->minWidth = width; w->minHeight = height; @@ -1487,20 +1465,22 @@ void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, co w->base.convertPercents = false; w->base.padding = 3; w->base.lineHeight = Drawer2D_FontHeight(font, false); + + w->base.GetMaxLines = MenuInputWidget_GetMaxLines; + w->base.RemakeTexture = MenuInputWidget_RemakeTexture; + w->base.OnPressedEnter = InputWidget_OnPressedEnter; + w->base.AllowedChar = MenuInputWidget_AllowedChar; + String_InitArray(w->base.text, w->_textBuffer); - - w->base.GetMaxLines = MenuInputWidget_GetMaxLines; - w->base.RemakeTexture = MenuInputWidget_RemakeTexture; - w->base.AllowedChar = MenuInputWidget_AllowedChar; - - Elem_Init(&w->base); - InputWidget_AppendString(&w->base, text); + String_Copy(&w->base.text, text); } /*########################################################################################################################* *-----------------------------------------------------ChatInputWidget-----------------------------------------------------* *#########################################################################################################################*/ +static const String chatInputPrefix = String_FromConst("> "); + static void ChatInputWidget_RemakeTexture(void* widget) { String line; char lineBuffer[STRING_SIZE + 2]; struct InputWidget* w = (struct InputWidget*)widget; @@ -1520,11 +1500,8 @@ static void ChatInputWidget_RemakeTexture(void* widget) { if (!size.Height) size.Height = w->lineHeight; Bitmap_AllocateClearedPow2(&bmp, size.Width, size.Height); - DrawTextArgs_MakeEmpty(&args, w->font, true); - if (w->prefix.length) { - args.text = w->prefix; - Drawer2D_DrawText(&bmp, &args, 0, 0); - } + DrawTextArgs_Make(&args, &chatInputPrefix, w->font, true); + Drawer2D_DrawText(&bmp, &args, 0, 0); String_InitArray(line, lineBuffer); for (i = 0, y = 0; i < Array_Elems(w->lines); i++) { @@ -1729,28 +1706,34 @@ static int ChatInputWidget_GetMaxLines(void) { } static struct WidgetVTABLE ChatInputWidget_VTABLE = { - InputWidget_Init, ChatInputWidget_Render, InputWidget_Free, + Widget_NullFunc, ChatInputWidget_Render, InputWidget_Free, ChatInputWidget_KeyDown, InputWidget_KeyUp, InputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll, InputWidget_Reposition }; void ChatInputWidget_Create(struct ChatInputWidget* w, FontDesc* font) { - static const String prefix = String_FromConst("> "); - - InputWidget_Create(&w->base, font, &prefix); + struct DrawTextArgs args; + Widget_Reset(w); w->typingLogPos = Chat_InputLog.count; /* Index of newest entry + 1. */ w->base.VTABLE = &ChatInputWidget_VTABLE; + w->base.font = font; + 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; String_InitArray(w->base.text, w->_textBuffer); String_InitArray(w->origStr, w->_origBuffer); + + DrawTextArgs_Make(&args, &chatInputPrefix, font, true); + w->base.prefixWidth = Drawer2D_TextWidth(&args); } diff --git a/src/Widgets.h b/src/Widgets.h index f1030c773..4dfc39651 100644 --- a/src/Widgets.h +++ b/src/Widgets.h @@ -110,7 +110,6 @@ struct InputWidget { int lineWidths[INPUTWIDGET_MAX_LINES]; /* Width of each line in pixels */ int lineHeight; struct Texture inputTex; - String prefix; int prefixWidth; bool convertPercents;