Mostly port menu input validators to C.

This commit is contained in:
UnknownShadow200 2018-01-24 11:18:03 +11:00
parent b79d42e3fa
commit f86b7cc858
4 changed files with 231 additions and 15 deletions

View File

@ -36,3 +36,38 @@ void PackedCol_GetShaded(PackedCol normal, PackedCol* xSide, PackedCol* zSide, P
*zSide = PackedCol_Scale(normal, PACKEDCOL_SHADE_Z); *zSide = PackedCol_Scale(normal, PACKEDCOL_SHADE_Z);
*yMin = PackedCol_Scale(normal, PACKEDCOL_SHADE_YMIN); *yMin = PackedCol_Scale(normal, PACKEDCOL_SHADE_YMIN);
} }
bool PackedCol_Unhex(UInt8 hex, Int32* value) {
*value = 0;
if (hex >= '0' && hex <= '9') {
*value = (Int32)(hex - '0');
} else if (hex >= 'a' && hex <= 'f') {
*value = (Int32)(hex - 'a') + 10;
} else if (hex >= 'A' && hex <= 'F') {
*value = (Int32)(hex - 'A') + 10;
} else {
return false;
}
return true;
}
bool PackedCol_TryParseHex(STRING_PURE String* str, PackedCol* value) {
PackedCol empty = PACKEDCOL_CONST(0, 0, 0, 0); *value = empty;
/* accept XXYYZZ or #XXYYZZ forms */
if (str->length < 6) return false;
if (str->length > 6 && (str->buffer[0] != '#' || str->length > 7)) return false;
Int32 rH, rL, gH, gL, bH, bL;
UInt8* buffer = str->buffer;
if (buffer[0] == '#') buffer++;
if (!PackedCol_Unhex(buffer[0], &rH) || !PackedCol_Unhex(buffer[1], &rL)) return false;
if (!PackedCol_Unhex(buffer[2], &gH) || !PackedCol_Unhex(buffer[3], &gL)) return false;
if (!PackedCol_Unhex(buffer[4], &bH) || !PackedCol_Unhex(buffer[5], &bL)) return false;
value->R = (UInt8)(rH * 16 + rL);
value->G = (UInt8)(gH * 16 + gL);
value->B = (UInt8)(bH * 16 + bL);
value->A = UInt8_MaxValue;
return true;
}

View File

@ -1,6 +1,7 @@
#ifndef CC_PACKEDCOL_H #ifndef CC_PACKEDCOL_H
#define CC_PACKEDCOL_H #define CC_PACKEDCOL_H
#include "Typedefs.h" #include "Typedefs.h"
#include "String.h"
/* Manipulates an ARGB colour, in a format suitable for the native 3d graphics api. /* Manipulates an ARGB colour, in a format suitable for the native 3d graphics api.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/ */
@ -23,21 +24,14 @@ typedef struct PackedCol_ {
#define PACKEDCOL_CONST(r, g, b, a) { r, g, b, a }; #define PACKEDCOL_CONST(r, g, b, a) { r, g, b, a };
#endif #endif
/* Constructs a new ARGB colour. */
PackedCol PackedCol_Create4(UInt8 r, UInt8 g, UInt8 b, UInt8 a); PackedCol PackedCol_Create4(UInt8 r, UInt8 g, UInt8 b, UInt8 a);
/* Constructs a new ARGB colour. */
PackedCol PackedCol_Create3(UInt8 r, UInt8 g, UInt8 b); PackedCol PackedCol_Create3(UInt8 r, UInt8 g, UInt8 b);
/* Returns whether two packed colours are equal. */
#define PackedCol_Equals(a, b) ((a).Packed == (b).Packed) #define PackedCol_Equals(a, b) ((a).Packed == (b).Packed)
/* Converts a colour to ARGB form. */
#define PackedCol_ARGB(r, g, b, a) (((UInt32)(r) << 16) | ((UInt32)(g) << 8) | ((UInt32)(b)) | ((UInt32)(a) << 24)) #define PackedCol_ARGB(r, g, b, a) (((UInt32)(r) << 16) | ((UInt32)(g) << 8) | ((UInt32)(b)) | ((UInt32)(a) << 24))
/* Converts a colour to ARGB form. */
UInt32 PackedCol_ToARGB(PackedCol col); UInt32 PackedCol_ToARGB(PackedCol col);
/* Multiplies the RGB components by t, where t is in [0, 1] */
PackedCol PackedCol_Scale(PackedCol value, Real32 t); PackedCol PackedCol_Scale(PackedCol value, Real32 t);
/* Linearly interpolates the RGB components of both colours by t, where t is in [0, 1] */
PackedCol PackedCol_Lerp(PackedCol a, PackedCol b, Real32 t); PackedCol PackedCol_Lerp(PackedCol a, PackedCol b, Real32 t);
bool PackedCol_TryParseHex(STRING_PURE String* str, PackedCol* value);
#define PACKEDCOL_SHADE_X 0.6f #define PACKEDCOL_SHADE_X 0.6f
#define PACKEDCOL_SHADE_Z 0.8f #define PACKEDCOL_SHADE_Z 0.8f

View File

@ -1538,6 +1538,179 @@ void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String*
widget->PrefixHeight = (UInt16)size.Height; widget->Base.Height = size.Height; widget->PrefixHeight = (UInt16)size.Height; widget->Base.Height = size.Height;
} }
bool MenuInputValidator_AlwaysValidChar(MenuInputValidator* validator, UInt8 c) { return true; }
bool MenuInputValidator_AlwaysValidString(MenuInputValidator* validator, STRING_PURE String* s) { return true; }
void HexColourValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(#000000 - #FFFFFF)");
}
bool HexColourValidator_IsValidChar(MenuInputValidator* validator, UInt8 c) {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}
bool HexColourValidator_IsValidString(MenuInputValidator* validator, STRING_PURE String* s) {
return s->length <= 6;
}
bool HexColourValidator_IsValidValue(MenuInputValidator* validator, STRING_PURE String* s) {
PackedCol col;
return PackedCol_TryParseHex(s, &col);
}
MenuInputValidator MenuInputValidator_Hex(void) {
MenuInputValidator validator;
validator.GetRange = HexColourValidator_GetRange;
validator.IsValidChar = HexColourValidator_IsValidChar;
validator.IsValidString = HexColourValidator_IsValidString;
validator.IsValidValue = HexColourValidator_IsValidValue;
return validator;
}
void IntegerValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(");
String_AppendInt32(range, (Int32)validator->Meta1);
String_AppendConst(range, " - ");
String_AppendInt32(range, (Int32)validator->Meta2);
String_AppendConst(range, ")");
}
bool IntegerValidator_IsValidChar(MenuInputValidator* validator, UInt8 c) {
return (c >= '0' && c <= '9') || c == '-';
}
bool IntegerValidator_IsValidString(MenuInputValidator* validator, STRING_PURE String* s) {
Int32 value;
if (s->length == 1 && s->buffer[0] == '-') return true; /* input is just a minus sign */
return Convert_TryParseInt32(s, &value);
}
bool IntegerValidator_IsValidValue(MenuInputValidator* validator, STRING_PURE String* s) {
Int32 value;
if (!Convert_TryParseInt32(s, &value)) return false;
Int32 min = (Int32)validator->Meta1, max = (Int32)validator->Meta2;
return min <= value && value <= max;
}
MenuInputValidator MenuInputValidator_Integer(Int32 min, Int32 max) {
MenuInputValidator validator;
validator.GetRange = IntegerValidator_GetRange;
validator.IsValidChar = IntegerValidator_IsValidChar;
validator.IsValidString = IntegerValidator_IsValidString;
validator.IsValidValue = IntegerValidator_IsValidValue;
validator.Meta1 = (void*)min;
validator.Meta2 = (void*)max;
return validator;
}
void SeedValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(an integer)");
}
MenuInputValidator MenuInputValidator_Seed(void) {
MenuInputValidator validator = MenuInputValidator_Integer(Int32_MinValue, Int32_MaxValue);
validator.GetRange = SeedValidator_GetRange;
return validator;
}
void RealValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(");
String_AppendReal32(range, (Real32)validator->Meta1);
String_AppendConst(range, " - ");
String_AppendReal32(range, (Real32)validator->Meta2);
String_AppendConst(range, ")");
}
bool RealValidator_IsValidChar(MenuInputValidator* validator, UInt8 c) {
return (c >= '0' && c <= '9') || c == '-' || c == '.' || c == ',';
}
bool RealValidator_IsValidString(MenuInputValidator* validator, STRING_PURE String* s) {
Real32 value;
if (s->length == 1 && RealValidator_IsValidChar(validator, s->buffer[0])) return true;
return Convert_TryParseReal32(s, &value);
}
bool RealValidator_IsValidValue(MenuInputValidator* validator, STRING_PURE String* s) {
Real32 value;
if (!Convert_TryParseReal32(s, &value)) return false;
Real32 min = (Real32)validator->Meta1, max = (Real32)validator->Meta2;
return min <= value && value <= max;
}
MenuInputValidator MenuInputValidator_Real(Real32 min, Real32 max) {
MenuInputValidator validator;
validator.GetRange = RealValidator_GetRange;
validator.IsValidChar = RealValidator_IsValidChar;
validator.IsValidString = RealValidator_IsValidString;
validator.IsValidValue = RealValidator_IsValidValue;
validator.Meta1 = (void*)min;
validator.Meta2 = (void*)max;
return validator;
}
void PathValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(Enter name)");
}
bool PathValidator_IsValidChar(MenuInputValidator* validator, UInt8 c) {
return !(c == '/' || c == '\\' || c == '?' || c == '*' || c == ':'
|| c == '<' || c == '>' || c == '|' || c == '"' || c == '.');
}
MenuInputValidator MenuInputValidator_Path(void) {
MenuInputValidator validator;
validator.GetRange = PathValidator_GetRange;
validator.IsValidChar = PathValidator_IsValidChar;
validator.IsValidString = MenuInputValidator_AlwaysValidString;
validator.IsValidValue = MenuInputValidator_AlwaysValidString;
return validator;
}
void BooleanInputValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(yes or no)");
}
MenuInputValidator MenuInputValidator_Boolean(void) {
MenuInputValidator validator;
validator.GetRange = BooleanInputValidator_GetRange;
validator.IsValidChar = MenuInputValidator_AlwaysValidChar;
validator.IsValidString = MenuInputValidator_AlwaysValidString;
validator.IsValidValue = MenuInputValidator_AlwaysValidString;
return validator;
}
MenuInputValidator MenuInputValidator_Enum(const UInt8** names, UInt32 namesCount) {
MenuInputValidator validator = MenuInputValidator_Boolean();
validator.Meta1 = names;
validator.Meta2 = (void*)namesCount;
return validator;
}
void StringValidator_GetRange(MenuInputValidator* validator, STRING_TRANSIENT String* range) {
String_AppendConst(range, "&7(Enter text)");
}
bool StringValidator_IsValidChar(MenuInputValidator* validator, UInt8 c) {
return c != '&' && Utils_IsValidInputChar(c, true);
}
bool StringValidator_IsValidString(MenuInputValidator* validator, STRING_PURE String* s) {
return s->length <= STRING_SIZE;
}
MenuInputValidator MenuInputValidator_String(void) {
MenuInputValidator validator;
validator.GetRange = StringValidator_GetRange;
validator.IsValidChar = StringValidator_IsValidChar;
validator.IsValidString = StringValidator_IsValidString;
validator.IsValidValue = StringValidator_IsValidString;
return validator;
}
void MenuInputWidget_Render(GuiElement* elem, Real64 delta) { void MenuInputWidget_Render(GuiElement* elem, Real64 delta) {
Widget* elemW = (Widget*)elem; Widget* elemW = (Widget*)elem;
PackedCol backCol = PACKEDCOL_CONST(30, 30, 30, 200); PackedCol backCol = PACKEDCOL_CONST(30, 30, 30, 200);
@ -1561,7 +1734,8 @@ void MenuInputWidget_RemakeTexture(GuiElement* elem) {
UInt8 rangeBuffer[String_BufferSize(STRING_SIZE)]; UInt8 rangeBuffer[String_BufferSize(STRING_SIZE)];
String range = String_InitAndClearArray(rangeBuffer); String range = String_InitAndClearArray(rangeBuffer);
widget->Validator.GetRange(&range); MenuInputValidator* validator = &widget->Validator;
validator->GetRange(validator, &range);
/* Ensure we don't have 0 text height */ /* Ensure we don't have 0 text height */
if (size.Height == 0) { if (size.Height == 0) {
@ -1600,14 +1774,15 @@ bool MenuInputWidget_AllowedChar(GuiElement* elem, UInt8 c) {
if (c == '&' || !Utils_IsValidInputChar(c, true)) return false; if (c == '&' || !Utils_IsValidInputChar(c, true)) return false;
MenuInputWidget* widget = (MenuInputWidget*)elem; MenuInputWidget* widget = (MenuInputWidget*)elem;
InputWidget* elemW = (InputWidget*)elem; InputWidget* elemW = (InputWidget*)elem;
MenuInputValidator* validator = &widget->Validator;
if (!widget->Validator.IsValidChar(c)) return false; if (!validator->IsValidChar(validator, c)) return false;
Int32 maxChars = elemW->GetMaxLines() * elemW->MaxCharsPerLine; Int32 maxChars = elemW->GetMaxLines() * elemW->MaxCharsPerLine;
if (elemW->Text.length == maxChars) return false; if (elemW->Text.length == maxChars) return false;
/* See if the new string is in valid format */ /* See if the new string is in valid format */
InputWidget_AppendChar(elemW, c); InputWidget_AppendChar(elemW, c);
bool valid = widget->Validator.IsValidString(&elemW->Text); bool valid = validator->IsValidString(validator, &elemW->Text);
InputWidget_DeleteChar(elemW); InputWidget_DeleteChar(elemW);
return valid; return valid;
} }

View File

@ -162,11 +162,23 @@ void InputWidget_Append(InputWidget* widget, UInt8 c);
typedef struct MenuInputValidator_ { typedef struct MenuInputValidator_ {
void (*GetRange)(STRING_TRANSIENT String* range); void (*GetRange)(struct MenuInputValidator_* validator, STRING_TRANSIENT String* range);
bool (*IsValidChar)(UInt8 c); bool (*IsValidChar)(struct MenuInputValidator_* validator, UInt8 c);
bool (*IsValidString)(STRING_PURE String* s); bool (*IsValidString)(struct MenuInputValidator_* validator, STRING_PURE String* s);
bool (*IsValidValue)(STRING_PURE String* s); bool (*IsValidValue)(struct MenuInputValidator_* validator, STRING_PURE String* s);
void* Meta1; /* TODO: do we need to handle when sizeof(void*) is < 32 bits? */
void* Meta2; /* TODO: do we need to handle when sizeof(void*) is < 32 bits? */
} MenuInputValidator; } MenuInputValidator;
MenuInputValidator MenuInputValidator_Hex(void);
MenuInputValidator MenuInputValidator_Integer(Int32 min, Int32 max);
MenuInputValidator MenuInputValidator_Seed(void);
MenuInputValidator MenuInputValidator_Real(Real32 min, Real32 max);
MenuInputValidator MenuInputValidator_Path(void);
MenuInputValidator MenuInputValidator_Boolean(void);
MenuInputValidator MenuInputValidator_Enum(const UInt8** names, UInt32 namesCount);
MenuInputValidator MenuInputValidator_String(void);
typedef struct MenuInputWidget_ { typedef struct MenuInputWidget_ {
InputWidget Base; InputWidget Base;
Int32 MinWidth, MinHeight; Int32 MinWidth, MinHeight;