diff --git a/ClassicalSharp/2D/Widgets/InputWidget.cs b/ClassicalSharp/2D/Widgets/InputWidget.cs
index 0dfd771ad..52fb82b70 100644
--- a/ClassicalSharp/2D/Widgets/InputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/InputWidget.cs
@@ -19,7 +19,7 @@ namespace ClassicalSharp.Gui.Widgets {
DrawTextArgs args = new DrawTextArgs("_", font, true);
caretTex = game.Drawer2D.MakeTextTexture(ref args, 0, 0);
caretTex.Width = (ushort)((caretTex.Width * 3) / 4);
- caretWidth = caretTex.Width; caretHeight = caretTex.Height;
+ caretWidth = caretTex.Width;
if (Prefix == null) return;
args = new DrawTextArgs(Prefix, font, true);
@@ -38,7 +38,7 @@ namespace ClassicalSharp.Gui.Widgets {
protected int caret = -1;
protected Texture inputTex, caretTex, prefixTex;
protected readonly Font font;
- protected int caretWidth, caretHeight, prefixWidth, prefixHeight;
+ protected int caretWidth, prefixWidth, prefixHeight;
protected FastColour caretColour;
/// The raw text entered.
@@ -447,7 +447,7 @@ namespace ClassicalSharp.Gui.Widgets {
mouseX -= inputTex.X1; mouseY -= inputTex.Y1;
DrawTextArgs args = new DrawTextArgs(null, font, true);
IDrawer2D drawer = game.Drawer2D;
- int offset = 0, elemHeight = caretHeight;
+ int offset = 0, elemHeight = caretTex.Height;
string oneChar = new String('A', 1);
for (int y = 0; y < lines.Length; y++) {
diff --git a/src/Client/Picking.h b/src/Client/Picking.h
index 4c4689f30..697aae7c8 100644
--- a/src/Client/Picking.h
+++ b/src/Client/Picking.h
@@ -5,7 +5,7 @@
#include "Vectors.h"
#include "BlockID.h"
/* Data for picking/selecting block by the user, and clipping the camera.
-Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
+ Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
/* Describes the picked/selected block by the user and its position. */
diff --git a/src/Client/Widgets.c b/src/Client/Widgets.c
index 52bc3562b..069614a51 100644
--- a/src/Client/Widgets.c
+++ b/src/Client/Widgets.c
@@ -1095,6 +1095,14 @@ void SpecialInputWidget_Create(SpecialInputWidget* widget, FontDesc* font, Speci
}
+bool InputWidget_ControlDown(void) {
+#if CC_BUILD_OSX
+ return Key_IsWinPressed();
+#else
+ return Key_IsControlPressed();
+#endif
+}
+
void InputWidget_CalculateLineSizes(InputWidget* widget) {
Int32 y;
for (y = 0; y < INPUTWIDGET_MAX_LINES; y++) {
@@ -1126,7 +1134,7 @@ UInt8 InputWidget_GetLastCol(InputWidget* widget, Int32 indexX, Int32 indexY) {
}
void InputWidget_UpdateCaret(InputWidget* widget) {
- Int32 maxChars = widget->GetMaxLines() * widget->MaxCharsPerLine;
+ Int32 maxChars = widget->GetMaxLines() * INPUTWIDGET_LEN;
if (widget->CaretPos >= maxChars) widget->CaretPos = -1;
WordWrap_GetCoords(widget->CaretPos, widget->Lines, widget->GetMaxLines(), &widget->CaretX, &widget->CaretY);
DrawTextArgs args; DrawTextArgs_MakeEmpty(&args, &widget->Font, false);
@@ -1134,7 +1142,7 @@ void InputWidget_UpdateCaret(InputWidget* widget) {
/* Caret is at last character on line */
Widget* elem = &widget->Base;
- if (widget->CaretX == widget->MaxCharsPerLine) {
+ if (widget->CaretX == INPUTWIDGET_LEN) {
widget->CaretTex.X = elem->X + widget->Padding + widget->LineSizes[widget->CaretY].Width;
PackedCol yellow = PACKEDCOL_YELLOW; widget->CaretCol = yellow;
widget->CaretTex.Width = widget->CaretWidth;
@@ -1173,7 +1181,8 @@ void InputWidget_RenderCaret(InputWidget* widget, Real64 delta) {
}
}
-void InputWidget_RemakeTexture(InputWidget* widget) {
+void InputWidget_RemakeTexture(GuiElement* elem) {
+ InputWidget* widget = (InputWidget*)elem;
Int32 totalHeight = 0, maxWidth = 0, i;
for (i = 0; i < widget->GetMaxLines(); i++) {
totalHeight += widget->LineSizes[i].Height;
@@ -1215,15 +1224,16 @@ void InputWidget_RemakeTexture(InputWidget* widget) {
Drawer2D_End();
Platform_MemFree(bmp.Scan0);
- Widget* elem = &widget->Base;
- elem->Width = size.Width;
- elem->Height = realHeight == 0 ? widget->PrefixHeight : realHeight;
- elem->Reposition(elem);
- widget->InputTex.X = elem->X + widget->Padding;
- widget->InputTex.Y = elem->Y;
+ Widget* elemW = &widget->Base;
+ elemW->Width = size.Width;
+ elemW->Height = realHeight == 0 ? widget->PrefixHeight : realHeight;
+ elemW->Reposition(elemW);
+ widget->InputTex.X = elemW->X + widget->Padding;
+ widget->InputTex.Y = elemW->Y;
}
-void InputWidget_OnPressedEnter(InputWidget* widget) {
+void InputWidget_OnPressedEnter(GuiElement* elem) {
+ InputWidget* widget = (InputWidget*)elem;
InputWidget_Clear(widget);
widget->Base.Height = widget->PrefixHeight;
}
@@ -1254,7 +1264,7 @@ void InputWidget_AppendChar(InputWidget* widget, UInt8 c) {
}
bool InputWidget_TryAppendChar(InputWidget* widget, UInt8 c) {
- Int32 maxChars = widget->GetMaxLines() * widget->MaxCharsPerLine;
+ Int32 maxChars = widget->GetMaxLines() * INPUTWIDGET_LEN;
if (widget->Text.length >= maxChars) return false;
if (!widget->AllowedChar(&widget->Base.Base, c)) return false;
@@ -1297,8 +1307,8 @@ bool InputWidget_CheckCol(InputWidget* widget, Int32 index) {
return (code == '%' || code == '&') && Drawer2D_ValidColCode(col);
}
-void InputWidget_BackspaceKey(InputWidget* widget, bool controlDown) {
- if (controlDown) {
+void InputWidget_BackspaceKey(InputWidget* widget) {
+ if (InputWidget_ControlDown()) {
if (widget->CaretPos == -1) { widget->CaretPos = widget->Text.length - 1; }
Int32 len = WordWrap_GetBackLength(&widget->Text, widget->CaretPos);
if (len == 0) return;
@@ -1342,8 +1352,8 @@ void InputWidget_DeleteKey(InputWidget* widget) {
}
}
-void InputWidget_LeftKey(InputWidget* widget, bool controlDown) {
- if (controlDown) {
+void InputWidget_LeftKey(InputWidget* widget) {
+ if (InputWidget_ControlDown()) {
if (widget->CaretPos == -1) { widget->CaretPos = widget->Text.length - 1; }
widget->CaretPos -= WordWrap_GetBackLength(&widget->Text, widget->CaretPos);
InputWidget_UpdateCaret(widget);
@@ -1358,8 +1368,8 @@ void InputWidget_LeftKey(InputWidget* widget, bool controlDown) {
}
}
-void InputWidget_RightKey(InputWidget* widget, bool controlDown) {
- if (controlDown) {
+void InputWidget_RightKey(InputWidget* widget) {
+ if (InputWidget_ControlDown()) {
widget->CaretPos += WordWrap_GetForwardLength(&widget->Text, widget->CaretPos);
if (widget->CaretPos >= widget->Text.length) { widget->CaretPos = -1; }
InputWidget_UpdateCaret(widget);
@@ -1385,7 +1395,7 @@ void InputWidget_EndKey(InputWidget* widget) {
}
bool InputWidget_OtherKey(InputWidget* widget, Key key) {
- Int32 maxChars = widget->GetMaxLines() * widget->MaxCharsPerLine;
+ Int32 maxChars = widget->GetMaxLines() * INPUTWIDGET_LEN;
if (key == Key_V && widget->Text.length < maxChars) {
UInt8 textBuffer[String_BufferSize(INPUTWIDGET_MAX_LINES * STRING_SIZE)];
String text = String_InitAndClearArray(textBuffer);
@@ -1406,14 +1416,15 @@ void InputWidget_Init(GuiElement* elem) {
InputWidget* widget = (InputWidget*)elem;
Int32 lines = widget->GetMaxLines();
if (lines > 1) {
- WordWrap_Do(&widget->Text, widget->Lines, lines, widget->MaxCharsPerLine);
+ /* TODO: Actually make this work */
+ WordWrap_Do(&widget->Text, widget->Lines, lines, INPUTWIDGET_LEN);
} else {
String_Clear(&widget->Lines[0]);
String_AppendString(&widget->Lines[0], &widget->Text);
}
InputWidget_CalculateLineSizes(widget);
- InputWidget_RemakeTexture(widget);
+ InputWidget_RemakeTexture(elem);
InputWidget_UpdateCaret(widget);
}
@@ -1421,7 +1432,6 @@ void InputWidget_Free(GuiElement* elem) {
InputWidget* widget = (InputWidget*)elem;
Gfx_DeleteTexture(&widget->InputTex.ID);
Gfx_DeleteTexture(&widget->CaretTex.ID);
- Gfx_DeleteTexture(&widget->PrefixTex.ID);
}
void InputWidget_Recreate(GuiElement* elem) {
@@ -1440,26 +1450,21 @@ void InputWidget_Reposition(Widget* elem) {
}
bool InputWidget_HandlesKeyDown(GuiElement* elem, Key key) {
-#if CC_BUILD_OSX
- bool clipboardDown = Key_IsWinPressed();
-#else
- bool clipboardDown = Key_IsControlPressed();
-#endif
InputWidget* widget = (InputWidget*)elem;
if (key == Key_Left) {
- InputWidget_LeftKey(widget, clipboardDown);
+ InputWidget_LeftKey(widget);
} else if (key == Key_Right) {
- InputWidget_RightKey(widget, clipboardDown);
+ InputWidget_RightKey(widget);
} else if (key == Key_BackSpace) {
- InputWidget_BackspaceKey(widget, clipboardDown);
+ InputWidget_BackspaceKey(widget);
} else if (key == Key_Delete) {
InputWidget_DeleteKey(widget);
} else if (key == Key_Home) {
InputWidget_HomeKey(widget);
} else if (key == Key_End) {
InputWidget_EndKey(widget);
- } else if (clipboardDown && !InputWidget_OtherKey(widget, key)) {
+ } else if (InputWidget_ControlDown() && !InputWidget_OtherKey(widget, key)) {
return false;
}
return true;
@@ -1478,7 +1483,7 @@ bool InputWidget_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButto
if (button == MouseButton_Left) {
x -= widget->InputTex.X; y -= widget->InputTex.Y;
DrawTextArgs args; DrawTextArgs_MakeEmpty(&args, &widget->Font, true);
- Int32 offset = 0, charHeight = widget->CaretHeight;
+ Int32 offset = 0, charHeight = widget->CaretTex.Height;
Int32 charX, i;
for (i = 0; i < widget->GetMaxLines(); i++) {
@@ -1512,7 +1517,6 @@ void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String*
widget->Font = *font;
widget->Prefix = *prefix;
widget->CaretPos = -1;
- widget->MaxCharsPerLine = STRING_SIZE;
widget->RemakeTexture = InputWidget_RemakeTexture;
widget->OnPressedEnter = InputWidget_OnPressedEnter;
widget->AllowedChar = InputWidget_AllowedChar;
@@ -1531,8 +1535,7 @@ void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String*
DrawTextArgs args; DrawTextArgs_Make(&args, &caret, font, true);
widget->CaretTex = Drawer2D_MakeTextTexture(&args, 0, 0);
widget->CaretTex.Width = (UInt16)((widget->CaretTex.Width * 3) / 4);
- widget->CaretWidth = (UInt16)widget->CaretTex.Width;
- widget->CaretHeight = (UInt16)widget->CaretTex.Height;
+ widget->CaretWidth = (UInt16)widget->CaretTex.Width;
if (prefix->length == 0) return;
DrawTextArgs_Make(&args, prefix, font, true);
@@ -1781,7 +1784,7 @@ bool MenuInputWidget_AllowedChar(GuiElement* elem, UInt8 c) {
MenuInputValidator* validator = &widget->Validator;
if (!validator->IsValidChar(validator, c)) return false;
- Int32 maxChars = elemW->GetMaxLines() * elemW->MaxCharsPerLine;
+ Int32 maxChars = elemW->GetMaxLines() * INPUTWIDGET_LEN;
if (elemW->Text.length == maxChars) return false;
/* See if the new string is in valid format */
@@ -1811,13 +1814,190 @@ void MenuInputWidget_Create(MenuInputWidget* widget, Int32 width, Int32 height,
}
+void ChatInputWidget_Render(GuiElement* elem, Real64 delta) {
+ ChatInputWidget* widget = (ChatInputWidget*)elem;
+ InputWidget* input = (InputWidget*)elem;
+ Gfx_SetTexturing(false);
+ Int32 x = input->Base.X, y = input->Base.Y;
+
+ UInt32 i;
+ for (i = 0; i < INPUTWIDGET_MAX_LINES; i++) {
+ if (i > 0 && input->LineSizes[i].Height == 0) break;
+ bool caretAtEnd = (input->CaretY == i) && (input->CaretX == INPUTWIDGET_LEN || input->CaretPos == -1);
+ Int32 drawWidth = input->LineSizes[i].Width + (caretAtEnd ? input->CaretTex.Width : 0);
+ /* Cover whole window width to match original classic behaviour */
+ if (Game_PureClassic) {
+ drawWidth = max(drawWidth, Game_Width - x * 4);
+ }
+
+ PackedCol backCol = PACKEDCOL_CONST(0, 0, 0, 127);
+ GfxCommon_Draw2DFlat(x, y, drawWidth + input->Padding * 2, input->PrefixHeight, backCol);
+ y += input->LineSizes[i].Height;
+ }
+
+ Gfx_SetTexturing(true);
+ Texture_Render(&input->InputTex);
+ InputWidget_RenderCaret(input, delta);
+}
+
+void ChatInputWidget_OnPressedEnter(GuiElement* elem) {
+ ChatInputWidget* widget = (ChatInputWidget*)elem;
+
+ /* Don't want trailing spaces in output message */
+ String text = widget->Base.Text;
+ while (text.length > 0 && text.buffer[text.length - 1] == ' ') { text.length--; }
+ if (text.length > 0) { Chat_Send(&text); }
+
+ String orig = String_FromRawArray(widget->OrigBuffer);
+ String_Clear(&orig);
+ widget->TypingLogPos = Chat_InputLog.Count; /* Index of newest entry + 1. */
+
+ String empty = String_MakeNull();
+ Chat_AddOf(&empty, MESSAGE_TYPE_CLIENTSTATUS_2);
+ Chat_AddOf(&empty, MESSAGE_TYPE_CLIENTSTATUS_3);
+ InputWidget_OnPressedEnter(elem);
+}
+
+void ChatInputWidget_UpKey(GuiElement* elem) {
+ ChatInputWidget* widget = (ChatInputWidget*)elem;
+ InputWidget* input = (InputWidget*)elem;
+
+ if (InputWidget_ControlDown()) {
+ Int32 pos = input->CaretPos == -1 ? input->Text.length : input->CaretPos;
+ if (pos < INPUTWIDGET_LEN) return;
+
+ input->CaretPos = pos - INPUTWIDGET_LEN;
+ InputWidget_UpdateCaret(input);
+ return;
+ }
+
+ if (widget->TypingLogPos == Chat_InputLog.Count) {
+ String orig = String_FromRawArray(widget->OrigBuffer);
+ String_Clear(&orig);
+ String_AppendString(&orig, &input->Text);
+ }
+
+ if (Chat_InputLog.Count == 0) return;
+ widget->TypingLogPos--;
+ String_Clear(&input->Text);
+
+ if (widget->TypingLogPos < 0) widget->TypingLogPos = 0;
+ String prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, widget->TypingLogPos);
+ String_AppendString(&input->Text, &prevInput);
+
+ input->CaretPos = -1;
+ elem->Recreate(elem);
+}
+
+void ChatInputWidget_DownKey(GuiElement* elem) {
+ ChatInputWidget* widget = (ChatInputWidget*)elem;
+ InputWidget* input = (InputWidget*)elem;
+
+ if (InputWidget_ControlDown()) {
+ Int32 lines = input->GetMaxLines();
+ if (input->CaretPos == -1 || input->CaretPos >= (lines - 1) * INPUTWIDGET_LEN) return;
+
+ input->CaretPos += INPUTWIDGET_LEN;
+ InputWidget_UpdateCaret(input);
+ return;
+ }
+
+ if (Chat_InputLog.Count == 0) return;
+ widget->TypingLogPos++;
+ String_Clear(&input->Text);
+
+ if (widget->TypingLogPos >= Chat_InputLog.Count) {
+ widget->TypingLogPos = Chat_InputLog.Count;
+ String orig = String_FromRawArray(widget->OrigBuffer);
+ if (orig.length > 0) { String_AppendString(&input->Text, &orig); }
+ } else {
+ String prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, widget->TypingLogPos);
+ String_AppendString(&input->Text, &prevInput);
+ }
+
+ input->CaretPos = -1;
+ elem->Recreate(elem);
+}
+
+bool ChatInputWidget_IsNameChar(char c) {
+ return c == '_' || c == '.' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+void ChatInputWidget_TabKey(GuiElement* elem) {
+ ChatInputWidget* widget = (ChatInputWidget*)elem;
+ InputWidget* input = (InputWidget*)elem;
+
+ Int32 end = input->CaretPos == -1 ? input->Text.length - 1 : input->CaretPos;
+ Int32 start = end;
+ UInt8* buffer = input->Text.buffer;
+
+ while (start >= 0 && ChatInputWidget_IsNameChar(buffer[start])) { start--; }
+ start++;
+ if (end < 0 || start > end) return;
+
+ String part = String_UNSAFE_Substring(&input->Text, start, (end + 1) - start);
+ String empty = String_MakeNull();
+ Chat_AddOf(&empty, MESSAGE_TYPE_CLIENTSTATUS_3);
+
+ EntityID matches[TABLIST_MAX_NAMES];
+ UInt32 i, matchesCount = 0;
+
+ for (i = 0; i < TABLIST_MAX_NAMES; i++) {
+ EntityID id = (EntityID)i;
+ if (!TabList_Valid(id)) continue;
+
+ String name = TabList_UNSAFE_GetPlayer(i);
+ if (!String_CaselessStarts(&name, &part)) continue;
+ matches[matchesCount++] = id;
+ }
+
+ if (matchesCount == 1) {
+ if (input->CaretPos == -1) end++;
+ Int32 len = end - start, j;
+ for (j = 0; j < len; j++) {
+ String_DeleteAt(&input->Text, start);
+ }
+
+ if (input->CaretPos != -1) input->CaretPos -= len;
+ String match = TabList_UNSAFE_GetPlayer(matches[0]);
+ InputWidget_AppendString(input, &match);
+ } else if (matchesCount > 1) {
+ UInt8 strBuffer[String_BufferSize(STRING_SIZE)];
+ String str = String_InitAndClearArray(strBuffer);
+ String_AppendConst(&str, "&e");
+ String_AppendInt32(&str, matchesCount);
+ String_AppendConst(&str, " matching names: ");
+
+ for (i = 0; i < matchesCount; i++) {
+ String match = TabList_UNSAFE_GetPlayer(matches[i]);
+ if ((str.length + match.length + 1) > STRING_SIZE) break;
+
+ String_AppendString(&str, &match);
+ String_Append(&str, ' ');
+ }
+ Chat_AddOf(&str, MESSAGE_TYPE_CLIENTSTATUS_3);
+ }
+}
+
+bool ChatInputWidget_HandlesKeyDown(GuiElement* elem, Key key) {
+ if (key == Key_Tab) { ChatInputWidget_TabKey(elem); return true; }
+ if (key == Key_Up) { ChatInputWidget_UpKey(elem); return true; }
+ if (key == Key_Down) { ChatInputWidget_DownKey(elem); return true; }
+ return InputWidget_HandlesKeyDown(elem, key);
+}
+
+Int32 ChatInputWidget_GetMaxLines(void) {
+ return !Game_ClassicMode && ServerConnection_SupportsPartialMessages ? 3 : 1;
+}
+
void ChatInputWidget_Create(ChatInputWidget* widget, FontDesc* font) {
String prefix = String_FromConst("> ");
InputWidget_Create(&widget->Base, font, &prefix);
widget->TypingLogPos = Chat_InputLog.Count; /* Index of newest entry + 1. */
- widget->Base.ShowCaret = true;
- widget->Base.Padding = 5;
+ widget->Base.ShowCaret = true;
+ widget->Base.Padding = 5;
widget->Base.GetMaxLines = ChatInputWidget_GetMaxLines;
widget->Base.OnPressedEnter = ChatInputWidget_OnPressedEnter;
@@ -1825,155 +2005,6 @@ void ChatInputWidget_Create(ChatInputWidget* widget, FontDesc* font) {
widget->Base.Base.Base.HandlesKeyDown = ChatInputWidget_HandlesKeyDown;
}
-Int32 ChatInputWidget_GetMaxLines(void) {
- return !Game_ClassicMode && ServerConnection_SupportsPartialMessages ? 3 : 1;
-}
-
-void ChatInputWidget_Render(GuiElement* elem, Real64 delta) {
- Gfx_SetTexturing(false);
- int y = Y, x = X;
-
- for (int i = 0; i < lineSizes.Length; i++) {
- if (i > 0 && lineSizes[i].Height == 0) break;
- bool caretAtEnd = (caretY == i) && (caretX == MaxCharsPerLine || caret == -1);
- int drawWidth = lineSizes[i].Width + (caretAtEnd ? (int)caretTex.Width : 0);
- /* Cover whole window width to match original classic behaviour */
- if (Game_PureClassic) {
- drawWidth = Math.Max(drawWidth, Game_Width - X * 4);
- }
-
- PackedCol backCol = PACKEDCOL_CONST(0, 0, 0, 127);
- GfxCommon_Draw2DQuad(x, y, drawWidth + Padding * 2, prefixHeight, backCol);
- y += lineSizes[i].Height;
- }
-
- Gfx_SetTexturing(true);
- inputTex.Render(game.Graphics);
- RenderCaret(delta);
-}
-
-void ChatInputWidget_OnPressedEnter(GuiElement* elem) {
- ChatInputWidget* widget = (ChatInputWidget*)elem;
- if (!Text.Empty) {
- // Don't want trailing spaces in output message
- string text = new String(Text.value, 0, Text.TextLength);
- game.Chat.Send(text);
- }
-
- originalText = null;
- widget->TypingLogPos = Chat_InputLog.Count; /* Index of newest entry + 1. */
-
- game.Chat.Add(null, MessageType.ClientStatus2);
- game.Chat.Add(null, MessageType.ClientStatus3);
- InputWidget_OnPressedEnter(elem);
-}
-
-bool ChatInputWidget_HandlesKeyDown(GuiElement* elem, Key key) {
- bool controlDown = ControlDown();
-
- if (key == Key_Tab) { TabKey(); return true; }
- if (key == Key_Up) { UpKey(controlDown); return true; }
- if (key == Key_Down) { DownKey(controlDown); return true; }
-
- return InputWidget_HandlesKeyDown(elem, key);
-}
-
-void ChatInputWidget_UpKey(bool controlDown) {
- if (controlDown) {
- int pos = caret == -1 ? Text.Length : caret;
- if (pos < MaxCharsPerLine) return;
-
- caret = pos - MaxCharsPerLine;
- UpdateCaret();
- return;
- }
-
- if (typingLogPos == Chat_InputLog.Count) {
- originalText = Text.ToString();
- }
-
- if (Chat_InputLog.Count == 0) return;
- typingLogPos--;
- Text.Clear();
-
- if (typingLogPos < 0) typingLogPos = 0;
- Text.Set(game.Chat.InputLog[typingLogPos]);
-
- caret = -1;
- Recreate();
-}
-
-void ChatInputWidget_DownKey(bool controlDown) {
- if (controlDown) {
- if (caret == -1 || caret >= (UsedLines - 1) * MaxCharsPerLine) return;
- caret += MaxCharsPerLine;
- UpdateCaret();
- return;
- }
-
- if (Chat_InputLog.Count == 0) return;
- typingLogPos++;
- Text.Clear();
-
- if (typingLogPos >= Chat_InputLog.Count) {
- typingLogPos = Chat_InputLog.Count;
- if (originalText != null) Text.Set(originalText);
- } else {
- Text.Set(game.Chat.InputLog[typingLogPos]);
- }
-
- caret = -1;
- Recreate();
-}
-
-void ChatInputWidget_TabKey() {
- int pos = caret == -1 ? Text.Length - 1 : caret;
- int start = pos;
- char[] value = Text.value;
-
- while (start >= 0 && IsNameChar(value[start]))
- start--;
- start++;
- if (pos < 0 || start > pos) return;
-
- string part = new String(value, start, pos + 1 - start);
- List matches = new List();
- game.Chat.Add(null, MessageType.ClientStatus3);
-
- TabListEntry[] entries = TabList.Entries;
- for (int i = 0; i < EntityList.MaxCount; i++) {
- if (entries[i] == null) continue;
- string name = entries[i].PlayerName;
- if (Utils.CaselessStarts(name, part)) matches.Add(name);
- }
-
- if (matches.Count == 1) {
- if (caret == -1) pos++;
- int len = pos - start;
- for (int i = 0; i < len; i++)
- Text.DeleteAt(start);
- if (caret != -1) caret -= len;
- Append(matches[0]);
- } else if (matches.Count > 1) {
- StringBuffer sb = new StringBuffer(Utils.StringLength);
- sb.Append("&e");
- sb.AppendNum(matches.Count);
- sb.Append(" matching names: ");
-
- for (int i = 0; i < matches.Count; i++) {
- string match = matches[i];
- if ((sb.Length + match.Length + 1) > sb.Capacity) break;
- sb.Append(match);
- sb.Append(' ');
- }
- game.Chat.Add(sb.ToString(), MessageType.ClientStatus3);
- }
-}
-
-bool ChatInputWidget_IsNameChar(char c) {
- return c == '_' || c == '.' || (c >= '0' && c <= '9')
- || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-}
#define GROUP_NAME_ID UInt16_MaxValue
diff --git a/src/Client/Widgets.h b/src/Client/Widgets.h
index df462bf04..5a16cd40c 100644
--- a/src/Client/Widgets.h
+++ b/src/Client/Widgets.h
@@ -121,11 +121,10 @@ void SpecialInputWidget_SetActive(SpecialInputWidget* widget, bool active);
#define INPUTWIDGET_MAX_LINES 3
-struct InputWidget_;
+#define INPUTWIDGET_LEN STRING_SIZE
typedef struct InputWidget_ {
Widget Base;
FontDesc Font;
- Int32 Padding, MaxCharsPerLine;
Int32 (*GetMaxLines)(void);
void (*RemakeTexture)(GuiElement* elem); /* Remakes the raw texture containing all the chat lines. Also updates dimensions. */
void (*OnPressedEnter)(GuiElement* elem); /* Invoked when the user presses enter. */
@@ -137,12 +136,12 @@ typedef struct InputWidget_ {
Texture InputTex;
String Prefix;
UInt16 PrefixWidth, PrefixHeight;
- Texture PrefixTex;
-
- Int32 CaretX, CaretY; /* Coordinates of caret in lines */
- UInt16 CaretWidth, CaretHeight;
- Int32 CaretPos; /* Position of caret, -1 for at end of string. */
+
+ UInt8 Padding;
bool ShowCaret;
+ UInt16 CaretWidth;
+ Int32 CaretX, CaretY; /* Coordinates of caret in lines */
+ Int32 CaretPos; /* Position of caret, -1 for at end of string. */
PackedCol CaretCol;
Texture CaretTex;
Real64 CaretAccumulator;
@@ -187,7 +186,7 @@ typedef struct MenuInputWidget_ {
InputWidget Base;
Int32 MinWidth, MinHeight;
MenuInputValidator Validator;
- UInt8 TextBuffer[String_BufferSize(STRING_SIZE)];
+ UInt8 TextBuffer[String_BufferSize(INPUTWIDGET_LEN)];
} MenuInputWidget;
void MenuInputWidget_Create(MenuInputWidget* widget, Int32 width, Int32 height, STRING_PURE String* text, FontDesc* font, MenuInputValidator* validator);
@@ -196,8 +195,8 @@ void MenuInputWidget_Create(MenuInputWidget* widget, Int32 width, Int32 height,
typedef struct ChatInputWidget_ {
InputWidget Base;
Int32 TypingLogPos;
- UInt8 TextBuffer[String_BufferSize(INPUTWIDGET_MAX_LINES * STRING_SIZE)];
- UInt8 OrigBuffer[String_BufferSize(INPUTWIDGET_MAX_LINES * STRING_SIZE)];
+ UInt8 TextBuffer[String_BufferSize(INPUTWIDGET_MAX_LINES * INPUTWIDGET_LEN)];
+ UInt8 OrigBuffer[String_BufferSize(INPUTWIDGET_MAX_LINES * INPUTWIDGET_LEN)];
} ChatInputWidget;
void ChatInputWidget_Create(ChatInputWidget* widget, FontDesc* font);