diff --git a/src/Camera.c b/src/Camera.c index 2c9a3a922..60846f842 100644 --- a/src/Camera.c +++ b/src/Camera.c @@ -7,6 +7,7 @@ #include "Gui.h" #include "Entity.h" #include "Input.h" +#include "Event.h" struct _CameraData Camera; static struct PickedPos cameraClipPos; diff --git a/src/Gui.h b/src/Gui.h index ff0c9ab6f..15ce74dc3 100644 --- a/src/Gui.h +++ b/src/Gui.h @@ -1,6 +1,5 @@ #ifndef CC_GUI_H #define CC_GUI_H -#include "Event.h" #include "VertexStructs.h" /* Describes and manages 2D GUI elements on screen. Copyright 2014-2019 ClassiCube | Licensed under BSD-3 diff --git a/src/Input.c b/src/Input.c index e68541f22..30b0a88a5 100644 --- a/src/Input.c +++ b/src/Input.c @@ -47,6 +47,7 @@ static struct TouchPointer { long id; cc_uint8 type; int begX, begY; + TimeMS start; } touches[INPUT_MAX_POINTERS]; int Pointers_Count; cc_bool Input_Placing; @@ -60,6 +61,11 @@ cc_bool Input_Placing; #define TOUCH_TYPE_BLOCKS 4 #define TOUCH_TYPE_ALL (TOUCH_TYPE_GUI | TOUCH_TYPE_CAMERA | TOUCH_TYPE_BLOCKS) +static void DoDeleteBlock(void); +static void DoPlaceBlock(void); +static void MouseStatePress(int button); +static void MouseStateRelease(int button); + static cc_bool AnyBlockTouches(void) { int i; for (i = 0; i < Pointers_Count; i++) { @@ -75,6 +81,12 @@ void Input_AddTouch(long id, int x, int y) { touches[i].begX = x; touches[i].begY = y; + touches[i].start = DateTime_CurrentUTC_MS(); + /* Also set last click time, otherwise quickly tapping */ + /* sometimes triggers a 'delete' in InputHandler_PickBlocks, */ + /* and then another 'delete' in CheckBlockTap. */ + input_lastClick = touches[i].start; + Pointers_Count++; Pointer_SetPosition(i, x, y); Pointer_SetPressed(i, true); @@ -96,7 +108,7 @@ void Input_UpdateTouch(long id, int x, int y) { if (touches[i].type == TOUCH_TYPE_ALL && MovedFromBeg(i, x, y)) { /* Allow a little bit of leeway because though, because devices */ /* might still report a few pixels of movement depending on how */ - /* user is holding the finger down on the toiuch surface */ + /* user is holding the finger down on the touch surface */ touches[i].type = TOUCH_TYPE_CAMERA; } Event_RaiseMove(&PointerEvents.RawMoved, i, x - Pointers[i].x, y - Pointers[i].y); @@ -106,12 +118,29 @@ void Input_UpdateTouch(long id, int x, int y) { } } +/* Quickly tapping should trigger a block place/delete */ +static void CheckBlockTap(int i) { + int btn, pressed; + if (DateTime_CurrentUTC_MS() > touches[i].start + 250) return; + if (touches[i].type != TOUCH_TYPE_ALL) return; + + btn = Input_Placing ? MOUSE_RIGHT : MOUSE_LEFT; + pressed = input_buttonsDown[btn]; + MouseStatePress(btn); + + if (btn == MOUSE_LEFT) { DoDeleteBlock(); } + else { DoPlaceBlock(); } + + if (!pressed) MouseStateRelease(btn); +} + void Input_RemoveTouch(long id, int x, int y) { int i; for (i = 0; i < Pointers_Count; i++) { if (touches[i].id != id) continue; Pointer_SetPosition(i, x, y); Pointer_SetPressed(i, false); + CheckBlockTap(i); /* found the touch, remove it */ for (; i < Pointers_Count - 1; i++) { @@ -639,7 +668,7 @@ static cc_bool CheckIsFree(BlockID block) { return true; } -static void InputHandler_DeleteBlock(void) { +static void DoDeleteBlock(void) { IVec3 pos; BlockID old; /* always play delete animations, even if we aren't deleting a block */ @@ -655,7 +684,7 @@ static void InputHandler_DeleteBlock(void) { Event_RaiseBlock(&UserEvents.BlockChanged, pos, old, BLOCK_AIR); } -static void InputHandler_PlaceBlock(void) { +static void DoPlaceBlock(void) { IVec3 pos; BlockID old, block; pos = Game_SelectedPos.TranslatedPos; @@ -674,7 +703,7 @@ static void InputHandler_PlaceBlock(void) { Event_RaiseBlock(&UserEvents.BlockChanged, pos, old, block); } -static void InputHandler_PickBlock(void) { +static void DoPickBlock(void) { IVec3 pos; BlockID cur; pos = Game_SelectedPos.BlockPos; @@ -715,11 +744,11 @@ void InputHandler_PickBlocks(void) { } if (left) { - InputHandler_DeleteBlock(); + DoDeleteBlock(); } else if (right) { - InputHandler_PlaceBlock(); + DoPlaceBlock(); } else if (middle) { - InputHandler_PickBlock(); + DoPickBlock(); } } @@ -804,13 +833,13 @@ static cc_bool HandleBlockKey(int key) { if (key == KeyBinds[KEYBIND_DELETE_BLOCK]) { MouseStatePress(MOUSE_LEFT); - InputHandler_DeleteBlock(); + DoDeleteBlock(); } else if (key == KeyBinds[KEYBIND_PLACE_BLOCK]) { MouseStatePress(MOUSE_RIGHT); - InputHandler_PlaceBlock(); + DoPlaceBlock(); } else if (key == KeyBinds[KEYBIND_PICK_BLOCK]) { MouseStatePress(MOUSE_MIDDLE); - InputHandler_PickBlock(); + DoPickBlock(); } else { return false; } diff --git a/src/Input.h b/src/Input.h index c8c6b7748..59541ffb2 100644 --- a/src/Input.h +++ b/src/Input.h @@ -70,7 +70,7 @@ void Input_SetPressed(int key, cc_bool pressed); /* Raises InputEvents.Up for each previously pressed button. */ void Input_Clear(void); -/* Whether raw mouse/touch input is being listened for. */ +/* Whether raw mouse/touch input is currently being listened for. */ extern cc_bool Input_RawMode; /* Whether touch input is being used. */ extern cc_bool Input_TouchMode; diff --git a/src/Menus.c b/src/Menus.c index 9d6159465..1c58015da 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -831,7 +831,7 @@ static int EditHotkeyScreen_KeyPress(void* screen, char keyChar) { static int EditHotkeyScreen_TextChanged(void* screen, const String* str) { #ifdef CC_BUILD_TOUCH struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; - InputWidget_SetAndSyncText(&s->input.base, str); + InputWidget_SetText(&s->input.base, str); #endif return true; } @@ -1023,7 +1023,7 @@ static int GenLevelScreen_KeyPress(void* screen, char keyChar) { static int GenLevelScreen_TextChanged(void* screen, const String* str) { #ifdef CC_BUILD_TOUCH struct GenLevelScreen* s = (struct GenLevelScreen*)screen; - if (s->selected) InputWidget_SetAndSyncText(&s->selected->base, str); + if (s->selected) InputWidget_SetText(&s->selected->base, str); #endif return true; } @@ -1377,7 +1377,7 @@ static int SaveLevelScreen_TextChanged(void* screen, const String* str) { #ifdef CC_BUILD_TOUCH struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; SaveLevelScreen_RemoveOverwrites(s); - InputWidget_SetAndSyncText(&s->input.base, str); + InputWidget_SetText(&s->input.base, str); #endif return true; } @@ -2055,7 +2055,7 @@ static int MenuOptionsScreen_KeyPress(void* screen, char keyChar) { static int MenuOptionsScreen_TextChanged(void* screen, const String* str) { #ifdef CC_BUILD_TOUCH struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; - if (s->activeI >= 0) InputWidget_SetAndSyncText(&s->input.base, str); + if (s->activeI >= 0) InputWidget_SetText(&s->input.base, str); #endif return true; } @@ -2112,14 +2112,11 @@ static void MenuOptionsScreen_OK(void* screen, void* widget) { static void MenuOptionsScreen_Default(void* screen, void* widget) { String value; char valueBuffer[STRING_SIZE]; struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; - struct MenuInputDesc* desc; + struct MenuInputDesc* desc = &s->descs[s->activeI]; - desc = &s->descs[s->activeI]; String_InitArray(value, valueBuffer); desc->VTABLE->GetDefault(desc, &value); - - InputWidget_Clear(&s->input.base); - InputWidget_AppendString(&s->input.base, &value); + InputWidget_SetText(&s->input.base, &value); } static void MenuOptionsScreen_Bool(void* screen, void* widget) { diff --git a/src/Screens.c b/src/Screens.c index bc04d983d..5ad570961 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -324,6 +324,9 @@ static struct ChatScreen { struct ChatInputWidget input; struct TextGroupWidget status, bottomRight, chat, clientStatus; struct SpecialInputWidget altText; +#ifdef CC_BUILD_TOUCH + struct ButtonWidget send, cancel; +#endif struct Texture statusTextures[CHAT_MAX_STATUS]; struct Texture bottomRightTextures[CHAT_MAX_BOTTOMRIGHT]; @@ -616,6 +619,12 @@ static void ChatScreen_DrawChat(struct ChatScreen* s, double delta) { if (s->altText.active) { Elem_Render(&s->altText, delta); } + +#ifdef CC_BUILD_TOUCH + if (!Input_TouchMode) return; + Elem_Render(&s->send, delta); + Elem_Render(&s->cancel, delta); +#endif } } @@ -638,6 +647,7 @@ static void ChatScreen_ContextLost(void* screen) { struct ChatScreen* s = (struct ChatScreen*)screen; Font_Free(&s->playerFont); ChatScreen_FreeChatFonts(s); + if (s->showingList) Elem_Free(&s->playerList); Elem_TryFree(&s->chat); Elem_TryFree(&s->input.base); @@ -647,7 +657,10 @@ static void ChatScreen_ContextLost(void* screen) { Elem_TryFree(&s->clientStatus); Elem_TryFree(&s->announcement); - if (s->showingList) Elem_Free(&s->playerList); +#ifdef CC_BUILD_TOUCH + Elem_TryFree(&s->send); + Elem_TryFree(&s->cancel); +#endif } static void ChatScreen_RemakePlayerList(struct ChatScreen* s) { @@ -660,6 +673,7 @@ static void ChatScreen_RemakePlayerList(struct ChatScreen* s) { static void ChatScreen_ContextRecreated(void* screen) { struct ChatScreen* s = (struct ChatScreen*)screen; int size = Drawer2D_BitmappedText ? 16 : 11; + struct FontDesc font; Drawer2D_MakeFont(&s->playerFont, size, FONT_STYLE_NORMAL); ChatScreen_ChatUpdateFont(s); @@ -667,6 +681,14 @@ static void ChatScreen_ContextRecreated(void* screen) { Widget_Layout(&s->hotbar); ChatScreen_ChatUpdateLayout(s); if (s->showingList) ChatScreen_RemakePlayerList(s); + +#ifdef CC_BUILD_TOUCH + if (!Input_TouchMode) return; + Drawer2D_MakeFont(&font, 16, FONT_STYLE_BOLD); + ButtonWidget_SetConst(&s->send, "Send", &font); + ButtonWidget_SetConst(&s->cancel, "Cancel", &font); + Font_Free(&font); +#endif } static void ChatScreen_BuildMesh(void* screen) { } @@ -678,6 +700,12 @@ static void ChatScreen_Layout(void* screen) { if (ChatScreen_ChatUpdateFont(s)) ChatScreen_Redraw(s); ChatScreen_ChatUpdateLayout(s); if (s->showingList) Widget_Layout(&s->playerList); + +#ifdef CC_BUILD_TOUCH + if (!Input_TouchMode) return; + Widget_Layout(&s->send); + Widget_Layout(&s->cancel); +#endif } static int ChatScreen_KeyPress(void* screen, char keyChar) { @@ -699,7 +727,7 @@ static int ChatScreen_TextChanged(void* screen, const String* str) { struct ChatScreen* s = (struct ChatScreen*)screen; if (!s->grabsInput) return false; - InputWidget_SetAndSyncText(&s->input.base, str); + InputWidget_SetText(&s->input.base, str); ChatScreen_UpdateChatYOffsets(s); #endif return true; @@ -806,6 +834,15 @@ static int ChatScreen_PointerDown(void* screen, int id, int x, int y) { if (Game_HideGui) return false; +#ifdef CC_BUILD_TOUCH + if (Widget_Contains(&s->send, x, y)) { + ChatScreen_EnterChatInput(s, false); return true; + } + if (Widget_Contains(&s->cancel, x, y)) { + ChatScreen_EnterChatInput(s, true); return true; + } +#endif + if (!Widget_Contains(&s->chat, x, y)) { if (s->altText.active && Widget_Contains(&s->altText, x, y)) { Elem_HandlesPointerDown(&s->altText, id, x, y); @@ -842,6 +879,12 @@ static void ChatScreen_Init(void* screen) { Event_RegisterInt(&TabListEvents.Added, s, ChatScreen_TabEntryAdded); Event_RegisterInt(&TabListEvents.Changed, s, ChatScreen_TabEntryChanged); Event_RegisterInt(&TabListEvents.Removed, s, ChatScreen_TabEntryRemoved); + +#ifdef CC_BUILD_TOUCH + if (!Input_TouchMode) return; + ButtonWidget_Make(&s->send, 100, NULL, ANCHOR_MAX, ANCHOR_MIN, 10, 10); + ButtonWidget_Make(&s->cancel, 100, NULL, ANCHOR_MAX, ANCHOR_MIN, 10, 60); +#endif } static void ChatScreen_Render(void* screen, double delta) { @@ -922,7 +965,7 @@ void ChatScreen_OpenInput(const String* text) { void ChatScreen_AppendInput(const String* text) { struct ChatScreen* s = &ChatScreen_Instance; - InputWidget_AppendString(&s->input.base, text); + InputWidget_AppendText(&s->input.base, text); ChatScreen_UpdateChatYOffsets(s); } @@ -1025,32 +1068,27 @@ static int InventoryScreen_KeyDown(void* screen, int key) { Gui_Remove((struct Screen*)s); } else if (Elem_HandlesKeyDown(table, key)) { } else { - struct ChatScreen* hud = (struct ChatScreen*)Gui_Chat; - return Elem_HandlesKeyDown(&hud->hotbar, key); + return Elem_HandlesKeyDown(&Gui_Chat->hotbar, key); } return true; } static int InventoryScreen_KeyUp(void* screen, int key) { struct InventoryScreen* s = (struct InventoryScreen*)screen; - struct ChatScreen* hud; if (key == KeyBinds[KEYBIND_INVENTORY]) { s->releasedInv = true; return true; } - - hud = (struct ChatScreen*)Gui_Chat; - return Elem_HandlesKeyUp(&hud->hotbar, key); + return Elem_HandlesKeyUp(&Gui_Chat->hotbar, key); } static int InventoryScreen_PointerDown(void* screen, int id, int x, int y) { struct InventoryScreen* s = (struct InventoryScreen*)screen; struct TableWidget* table = &s->table; - struct ChatScreen* hud = (struct ChatScreen*)Gui_Chat; cc_bool handled, hotbar; if (table->scroll.draggingId == id) return true; - if (Elem_HandlesPointerDown(&hud->hotbar, id, x, y)) return true; + if (Elem_HandlesPointerDown(&Gui_Chat->hotbar, id, x, y)) return true; handled = Elem_HandlesPointerDown(table, id, x, y); if (!handled || table->pendingClose) { @@ -1516,128 +1554,91 @@ void DisconnectScreen_Show(const String* title, const String* message) { #ifdef CC_BUILD_TOUCH static struct TouchScreen { Screen_Body - int numButtons, layout; - cc_uint8 binds[10]; + cc_uint8 binds[7]; struct FontDesc font; - struct ButtonWidget buttons[10]; -} TouchScreen_Instance; + struct ButtonWidget btns[7]; +} TouchScreen; + +static struct Widget* touch_widgets[7] = { + (struct Widget*)&TouchScreen.btns[0], (struct Widget*)&TouchScreen.btns[1], + (struct Widget*)&TouchScreen.btns[2], (struct Widget*)&TouchScreen.btns[3], + (struct Widget*)&TouchScreen.btns[4], (struct Widget*)&TouchScreen.btns[5], + (struct Widget*)&TouchScreen.btns[6], +}; +#define TOUCH_MAX_VERTICES (7 * BUTTONWIDGET_MAX) static const struct TouchBindDesc { const char* text; cc_uint8 bind, width; cc_int16 xOffset, yOffset; -} touchDescs[8] = { - { "<", KEYBIND_LEFT, 40, 150, 50 }, - { ">", KEYBIND_RIGHT, 40, 10, 50 }, - { "^", KEYBIND_FORWARD, 40, 80, 10 }, - { "\\/", KEYBIND_BACK, 40, 80, 90 }, - { "Jump", KEYBIND_JUMP, 100, 50, 150 }, - { "Mode", KEYBIND_COUNT, 100, 50, 190 }, - { "More", KEYBIND_COUNT, 100, 50, 230 }, - /* Chat labels */ - { "Send ", KEYBIND_SEND_CHAT, 100, 50, 10 }, +} touchDescs[7] = { + { "<", KEYBIND_LEFT, 40, 150, 50 }, + { ">", KEYBIND_RIGHT, 40, 10, 50 }, + { "^", KEYBIND_FORWARD, 40, 80, 10 }, + { "\\/", KEYBIND_BACK, 40, 80, 90 }, + { "Jump", KEYBIND_JUMP, 100, 50, 150 }, + { "", KEYBIND_COUNT, 100, 50, 190 }, + { "More", KEYBIND_COUNT, 100, 50, 230 }, }; -#define TOUCH_LAYOUT_FULL 0 -#define TOUCH_LAYOUT_CHAT 1 -#define TOUCH_LAYOUT_NONE 2 - -CC_NOINLINE static int CalcTouchMenuLayout(void) { - struct Screen* grabbed = Gui_GetInputGrab(); - if (!grabbed) return TOUCH_LAYOUT_FULL; - if (grabbed == &ChatScreen_Instance) return TOUCH_LAYOUT_CHAT; - return TOUCH_LAYOUT_NONE; -} - static void TouchScreen_ContextLost(void* screen) { struct TouchScreen* s = (struct TouchScreen*)screen; - int i; Font_Free(&s->font); - - for (i = 0; i < s->numButtons; i++) { - Elem_Free(&s->buttons[i]); - } + Screen_ContextLost(screen); } -CC_NOINLINE static void TouchScreen_Set(struct TouchScreen* s, int i, const char* text, KeyBind bind) { - ButtonWidget_SetConst(&s->buttons[i], text, &s->font); - s->binds[i] = bind; +static void TouchScreen_UpdateModeText(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + ButtonWidget_SetConst(&s->btns[5], Input_Placing ? "Place" : "Delete", &s->font); } -static void TouchScreen_ModeClick(void* s, void* w) { Input_Placing = !Input_Placing; } +static void TouchScreen_ModeClick(void* s, void* w) { + Input_Placing = !Input_Placing; + TouchScreen_UpdateModeText(s); +} static void TouchScreen_MoreClick(void* s, void* w) { TouchMoreOverlay_Show(); } static void TouchScreen_ContextRecreated(void* screen) { struct TouchScreen* s = (struct TouchScreen*)screen; const struct TouchBindDesc* desc; - int i, offset = 0; + int i; Drawer2D_MakeFont(&s->font, 16, FONT_STYLE_BOLD); - s->layout = CalcTouchMenuLayout(); - s->numButtons = 0; + s->vb = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FT2FC4B, TOUCH_MAX_VERTICES); - switch (s->layout) { - case TOUCH_LAYOUT_FULL: - s->numButtons = 7; - break; - case TOUCH_LAYOUT_CHAT: - offset = 7; - s->numButtons = 1; - break; + for (i = 0; i < s->numWidgets; i++) { + desc = &touchDescs[i]; + ButtonWidget_SetConst(&s->btns[i], desc->text, &s->font); } - - for (i = 0; i < s->numButtons; i++) { - desc = &touchDescs[i + offset]; - ButtonWidget_Make(&s->buttons[i], desc->width, NULL, ANCHOR_MAX, ANCHOR_MIN, - desc->xOffset, desc->yOffset); - ButtonWidget_SetConst(&s->buttons[i], desc->text, &s->font); - s->binds[i] = desc->bind; - } - + TouchScreen_UpdateModeText(s); /* TODO: Mode should display 'Place' or 'Delete' */ /* TODO: this is pretty nasty hacky. rewrite! */ - s->buttons[5].MenuClick = TouchScreen_ModeClick; - s->buttons[6].MenuClick = TouchScreen_MoreClick; } static void TouchScreen_Render(void* screen, double delta) { struct TouchScreen* s = (struct TouchScreen*)screen; - int i; + if (Gui_GetInputGrab()) return; Gfx_SetTexturing(true); - for (i = 0; i < s->numButtons; i++) { - Elem_Render(&s->buttons[i], delta); - } + Screen_Render2Widgets(screen, delta); Gfx_SetTexturing(false); - - i = CalcTouchMenuLayout(); - /* TODO: AWFUL AWFUL HACK */ - /* use guiEvents instead */ - if (i != s->layout) Gui_Refresh(s); -} - -static void TouchScreen_Layout(void* screen) { - struct TouchScreen* s = (struct TouchScreen*)screen; - int i; - for (i = 0; i < s->numButtons; i++) { - Widget_Layout(&s->buttons[i]); - } } static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { struct TouchScreen* s = (struct TouchScreen*)screen; int i; //Chat_Add1("POINTER DOWN: %i", &id); + if (Gui_GetInputGrab()) return false; - for (i = 0; i < s->numButtons; i++) { - if (!Widget_Contains(&s->buttons[i], x, y)) continue; + for (i = 0; i < s->numWidgets; i++) { + if (!Widget_Contains(&s->btns[i], x, y)) continue; if (s->binds[i] < KEYBIND_COUNT) { Input_SetPressed(KeyBinds[s->binds[i]], true); } else { - s->buttons[i].MenuClick(screen, &s->buttons[i]); + s->btns[i].MenuClick(screen, &s->btns[i]); } - s->buttons[i].active |= id; + s->btns[i].active |= id; return true; } return false; @@ -1648,29 +1649,54 @@ static int TouchScreen_PointerUp(void* screen, int id, int x, int y) { int i; //Chat_Add1("POINTER UP: %i", &id); - for (i = 0; i < s->numButtons; i++) { - if (!(s->buttons[i].active & id)) continue; + for (i = 0; i < s->numWidgets; i++) { + if (!(s->btns[i].active & id)) continue; if (s->binds[i] < KEYBIND_COUNT) { Input_SetPressed(KeyBinds[s->binds[i]], false); } - s->buttons[i].active &= ~id; + s->btns[i].active &= ~id; return true; } return false; } -static void TouchScreen_BuildMesh(void* screen) { } +static void TouchScreen_BuildMesh(void* screen) { + struct Screen* s = (struct Screen*)screen; + VertexP3fT2fC4b vertices[TOUCH_MAX_VERTICES]; + + Screen_BuildMesh(screen, vertices); + Gfx_SetDynamicVbData(s->vb, vertices, TOUCH_MAX_VERTICES); +} + +static void TouchScreen_Init(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + const struct TouchBindDesc* desc; + int i; + + s->widgets = touch_widgets; + s->numWidgets = Array_Elems(touch_widgets); + + for (i = 0; i < s->numWidgets; i++) { + desc = &touchDescs[i]; + ButtonWidget_Make(&s->btns[i], desc->width, NULL, ANCHOR_MAX, ANCHOR_MIN, + desc->xOffset, desc->yOffset); + s->binds[i] = desc->bind; + } + + s->btns[5].MenuClick = TouchScreen_ModeClick; + s->btns[6].MenuClick = TouchScreen_MoreClick; +} static const struct ScreenVTABLE TouchScreen_VTABLE = { - Screen_NullFunc, Screen_NullUpdate, Screen_NullFunc, + TouchScreen_Init, Screen_NullUpdate, Screen_NullFunc, TouchScreen_Render, TouchScreen_BuildMesh, Screen_FInput, Screen_FInput, Screen_FKeyPress, Screen_FText, TouchScreen_PointerDown, TouchScreen_PointerUp, Screen_FPointer, Screen_FMouseScroll, - TouchScreen_Layout, TouchScreen_ContextLost, TouchScreen_ContextRecreated + Screen_Layout, TouchScreen_ContextLost, TouchScreen_ContextRecreated }; void TouchScreen_Show(void) { - struct TouchScreen* s = &TouchScreen_Instance; + struct TouchScreen* s = &TouchScreen; s->VTABLE = &TouchScreen_VTABLE; if (!Input_TouchMode) return; diff --git a/src/Widgets.c b/src/Widgets.c index b133e4d61..e789b24fa 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -1060,7 +1060,7 @@ static cc_bool InputWidget_TryAppendChar(struct InputWidget* w, char c) { return true; } -void InputWidget_AppendString(struct InputWidget* w, const String* text) { +void InputWidget_AppendText(struct InputWidget* w, const String* text) { int i, appended = 0; for (i = 0; i < text->length; i++) { if (InputWidget_TryAppendChar(w, text->buffer[i])) appended++; @@ -1174,7 +1174,7 @@ static void InputWidget_EndKey(struct InputWidget* w) { } static void InputWidget_CopyFromClipboard(String* text, void* w) { - InputWidget_AppendString((struct InputWidget*)w, text); + InputWidget_AppendText((struct InputWidget*)w, text); } static cc_bool InputWidget_OtherKey(struct InputWidget* w, int key) { @@ -1204,12 +1204,14 @@ void InputWidget_UpdateText(struct InputWidget* w) { InputWidget_CalculateLineSizes(w); w->RemakeTexture(w); InputWidget_UpdateCaret(w); + Window_SetKeyboardText(&w->text); } -void InputWidget_SetAndSyncText(struct InputWidget* w, const String* str) { +void InputWidget_SetText(struct InputWidget* w, const String* str) { InputWidget_Clear(w); - InputWidget_AppendString(w, str); - Window_SetKeyboardText(&w->text); + InputWidget_AppendText(w, str); + /* If text is empty, InputWidget_UpdateText won't have been called */ + if (!w->text.length) Window_SetKeyboardText(&w->text); } static void InputWidget_Free(void* widget) { @@ -1723,7 +1725,7 @@ static void ChatInputWidget_TabKey(struct InputWidget* w) { if (w->caretPos != -1) w->caretPos -= len; name = TabList_UNSAFE_GetPlayer(matches[0]); - InputWidget_AppendString(w, &name); + InputWidget_AppendText(w, &name); } else if (numMatches > 1) { String_InitArray(str, strBuffer); String_Format1(&str, "&e%i matching names: ", &numMatches); @@ -2573,7 +2575,7 @@ static void SpecialInputWidget_IntersectsBody(struct SpecialInputWidget* w, int /* TODO: Not be so hacky */ if (w->selectedIndex == 0) str.length = 2; - InputWidget_AppendString(w->target, &str); + InputWidget_AppendText(w->target, &str); } static void SpecialInputTab_Init(struct SpecialInputTab* tab, STRING_REF String* title, int itemsPerRow, int charsPerItem, STRING_REF String* contents) { diff --git a/src/Widgets.h b/src/Widgets.h index 1d945dadc..0e1dbae5d 100644 --- a/src/Widgets.h +++ b/src/Widgets.h @@ -130,16 +130,19 @@ struct InputWidget { /* Removes all characters and then deletes the input texture. */ CC_NOINLINE void InputWidget_Clear(struct InputWidget* w); /* Tries appending all characters from the given string, then update the input texture. */ -CC_NOINLINE void InputWidget_AppendString(struct InputWidget* w, const String* text); +CC_NOINLINE void InputWidget_AppendText(struct InputWidget* w, const String* text); /* Tries appending the given character, then updates the input texture. */ CC_NOINLINE void InputWidget_Append(struct InputWidget* w, char c); /* Redraws text and recalculates associated state. */ +/* Also calls Window_SetKeyboardText with the text in the input widget. */ +/* This way native text input state stays synchronised with the input widget. */ +/* (e.g. may only accept numerical input, so 'c' gets stripped from str) */ CC_NOINLINE void InputWidget_UpdateText(struct InputWidget* w); -/* Shorthand for InputWidget_Clear followed by InputWidget_AppendString, */ +/* Shorthand for InputWidget_Clear followed by InputWidget_AppendText, */ /* then calls Window_SetKeyboardText with the text in the input widget. */ /* This way native text input state stays synchronised with the input widget. */ /* (e.g. may only accept numerical input, so 'c' gets stripped from str) */ -CC_NOINLINE void InputWidget_SetAndSyncText(struct InputWidget* w, const String* str); +CC_NOINLINE void InputWidget_SetText(struct InputWidget* w, const String* str); struct MenuInputDesc;