Merge pull request #616 from UnknownShadow200/GUIRE4

Improvements to mobile GUI and input
This commit is contained in:
UnknownShadow200 2020-01-23 10:31:56 +11:00 committed by GitHub
commit f156580b01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 183 additions and 126 deletions

View File

@ -7,6 +7,7 @@
#include "Gui.h"
#include "Entity.h"
#include "Input.h"
#include "Event.h"
struct _CameraData Camera;
static struct PickedPos cameraClipPos;

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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;