mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Mostly port menu input validators to C.
This commit is contained in:
parent
b79d42e3fa
commit
f86b7cc858
@ -36,3 +36,38 @@ void PackedCol_GetShaded(PackedCol normal, PackedCol* xSide, PackedCol* zSide, P
|
||||
*zSide = PackedCol_Scale(normal, PACKEDCOL_SHADE_Z);
|
||||
*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;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#ifndef CC_PACKEDCOL_H
|
||||
#define CC_PACKEDCOL_H
|
||||
#include "Typedefs.h"
|
||||
#include "String.h"
|
||||
/* Manipulates an ARGB colour, in a format suitable for the native 3d graphics api.
|
||||
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 };
|
||||
#endif
|
||||
|
||||
|
||||
/* Constructs a new ARGB colour. */
|
||||
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);
|
||||
/* Returns whether two packed colours are equal. */
|
||||
#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))
|
||||
/* Converts a colour to ARGB form. */
|
||||
UInt32 PackedCol_ToARGB(PackedCol col);
|
||||
/* Multiplies the RGB components by t, where t is in [0, 1] */
|
||||
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);
|
||||
bool PackedCol_TryParseHex(STRING_PURE String* str, PackedCol* value);
|
||||
|
||||
#define PACKEDCOL_SHADE_X 0.6f
|
||||
#define PACKEDCOL_SHADE_Z 0.8f
|
||||
|
@ -1538,6 +1538,179 @@ void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String*
|
||||
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) {
|
||||
Widget* elemW = (Widget*)elem;
|
||||
PackedCol backCol = PACKEDCOL_CONST(30, 30, 30, 200);
|
||||
@ -1561,7 +1734,8 @@ void MenuInputWidget_RemakeTexture(GuiElement* elem) {
|
||||
|
||||
UInt8 rangeBuffer[String_BufferSize(STRING_SIZE)];
|
||||
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 */
|
||||
if (size.Height == 0) {
|
||||
@ -1600,14 +1774,15 @@ bool MenuInputWidget_AllowedChar(GuiElement* elem, UInt8 c) {
|
||||
if (c == '&' || !Utils_IsValidInputChar(c, true)) return false;
|
||||
MenuInputWidget* widget = (MenuInputWidget*)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;
|
||||
if (elemW->Text.length == maxChars) return false;
|
||||
|
||||
/* See if the new string is in valid format */
|
||||
InputWidget_AppendChar(elemW, c);
|
||||
bool valid = widget->Validator.IsValidString(&elemW->Text);
|
||||
bool valid = validator->IsValidString(validator, &elemW->Text);
|
||||
InputWidget_DeleteChar(elemW);
|
||||
return valid;
|
||||
}
|
||||
|
@ -162,11 +162,23 @@ void InputWidget_Append(InputWidget* widget, UInt8 c);
|
||||
|
||||
|
||||
typedef struct MenuInputValidator_ {
|
||||
void (*GetRange)(STRING_TRANSIENT String* range);
|
||||
bool (*IsValidChar)(UInt8 c);
|
||||
bool (*IsValidString)(STRING_PURE String* s);
|
||||
bool (*IsValidValue)(STRING_PURE String* s);
|
||||
void (*GetRange)(struct MenuInputValidator_* validator, STRING_TRANSIENT String* range);
|
||||
bool (*IsValidChar)(struct MenuInputValidator_* validator, UInt8 c);
|
||||
bool (*IsValidString)(struct MenuInputValidator_* validator, 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_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_ {
|
||||
InputWidget Base;
|
||||
Int32 MinWidth, MinHeight;
|
||||
|
Loading…
x
Reference in New Issue
Block a user