add support for platform-specific setting values

also improves ccColor3B and ccColor4B hex string parsing (API break) and JsonMaybeValue::is (no break because templated)
This commit is contained in:
HJfod 2024-02-10 13:02:31 +02:00
parent d5742480a7
commit 9c8fcf15a9
5 changed files with 91 additions and 16 deletions
loader

View file

@ -140,12 +140,10 @@ namespace geode {
return *this;
}
template <matjson::Type T>
JsonMaybeValue& is() {
if (this->isError()) return *this;
self().m_hasValue = jsonConvertibleTo(self().m_json.type(), T);
m_inferType = false;
return *this;
template <class T>
bool is() {
if (this->isError()) return false;
return self().m_json.template is<T>();
}
template <class T>

View file

@ -816,8 +816,30 @@ namespace geode::cocos {
static_cast<GLubyte>(hexValue >> 0 & 0xff)};
}
GEODE_DLL Result<cocos2d::ccColor3B> cc3bFromHexString(std::string const& hexValue);
GEODE_DLL Result<cocos2d::ccColor4B> cc4bFromHexString(std::string const& hexValue);
/**
* Parse a ccColor3B from a hexadecimal string. The string may not contain
* a leading '#'
* @param hexValue The string to parse into a color
* @param permissive If true, strings like "f" are considered valid
* representations of the color white. Useful for UIs that allow entering
* a hex color. Empty strings evaluate to pure white
* @returns A ccColor3B if it could be succesfully parsed, or an error
* indicating the failure reason
*/
GEODE_DLL Result<cocos2d::ccColor3B> cc3bFromHexString(std::string const& hexValue, bool permissive = false);
/**
* Parse a ccColor4B from a hexadecimal string. The string may not contain
* a leading '#'
* @param hexValue The string to parse into a color
* @param requireAlpha Require the alpha component to be passed. If false,
* alpha defaults to 255
* @param permissive If true, strings like "f" are considered valid
* representations of the color white. Useful for UIs that allow entering
* a hex color. Empty strings evaluate to pure white
* @returns A ccColor4B if it could be succesfully parsed, or an error
* indicating the failure reason
*/
GEODE_DLL Result<cocos2d::ccColor4B> cc4bFromHexString(std::string const& hexValue, bool requireAlpha = false, bool permissive = false);
GEODE_DLL std::string cc3bToHexString(cocos2d::ccColor3B const& color);
GEODE_DLL std::string cc4bToHexString(cocos2d::ccColor4B const& color);

View file

@ -15,7 +15,21 @@ template<class T>
static void parseCommon(T& sett, JsonMaybeObject& obj) {
obj.has("name").into(sett.name);
obj.has("description").into(sett.description);
obj.has("default").into(sett.defaultValue);
if (auto defValue = obj.needs("default")) {
// Platform-specific default value
if (defValue.template is<matjson::Object>()) {
auto def = defValue.obj();
if (auto plat = def.has(PlatformID::toShortString(GEODE_PLATFORM_TARGET, true))) {
plat.into(sett.defaultValue);
}
else {
defValue.into(sett.defaultValue);
}
}
else {
defValue.into(sett.defaultValue);
}
}
}
Result<BoolSetting> BoolSetting::parse(JsonMaybeObject& obj) {

View file

@ -213,7 +213,7 @@ void ColorPickPopup::textChanged(CCTextInputNode* input) {
switch (input->getTag()) {
case TAG_HEX_INPUT:
{
if (auto color = cc3bFromHexString(input->getString())) {
if (auto color = cc3bFromHexString(input->getString(), true)) {
m_color.r = color.unwrap().r;
m_color.g = color.unwrap().g;
m_color.b = color.unwrap().b;

View file

@ -114,8 +114,8 @@ ccColor4B matjson::Serialize<ccColor4B>::from_json(matjson::Value const& json) {
return color;
}
Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& hexValue, bool permissive) {
if (permissive && hexValue.empty()) {
return Ok(ccc3(255, 255, 255));
}
if (hexValue.size() > 6) {
@ -142,21 +142,34 @@ Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& hexValue) {
} break;
case 2: {
if (!permissive) {
return Err("Invalid hex pattern, expected RGB or RRGGBB");
}
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc3(num, num, num));
} break;
case 1: {
if (!permissive) {
return Err("Invalid hex pattern, expected RGB or RRGGBB");
}
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc3(num, num, num));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, or 6");
default: {
if (permissive) {
return Err("Invalid hex pattern, expected R, RR, RGB, or RRGGBB");
}
else {
return Err("Invalid hex pattern, expected RGB or RRGGBB");
}
}
}
}
Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue, bool requireAlpha, bool permissive) {
if (permissive && hexValue.empty()) {
return Ok(ccc4(255, 255, 255, 255));
}
if (hexValue.size() > 8) {
@ -177,6 +190,9 @@ Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
} break;
case 6: {
if (requireAlpha) {
return Err("Alpha component is required, got only RRGGBB");
}
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
auto g = static_cast<uint8_t>((numValue & 0x00FF00) >> 8);
auto b = static_cast<uint8_t>((numValue & 0x0000FF));
@ -192,6 +208,9 @@ Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
} break;
case 3: {
if (requireAlpha) {
return Err("Alpha component is required, got only RGB");
}
auto r = static_cast<uint8_t>(((numValue & 0xF00) >> 8) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F0) >> 4) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F)) * 17);
@ -199,16 +218,38 @@ Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
} break;
case 2: {
if (!permissive) {
return Err("Invalid hex pattern, expected RGBA or RRGGBBAA");
}
if (requireAlpha) {
return Err("Alpha component is required, specify full RRGGBBAA");
}
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc4(num, num, num, 255));
} break;
case 1: {
if (!permissive) {
return Err("Invalid hex pattern, expected RGBA or RRGGBBAA");
}
if (requireAlpha) {
return Err("Alpha component is required, specify full RGBA");
}
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc4(num, num, num, 255));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, 4, 6, or 8");
default: {
if (requireAlpha) {
return Err("Invalid hex pattern, expected RGBA or RRGGBBAA");
}
else if (permissive) {
return Err("Invalid hex pattern, expected R, RR, RGB, RGBA, RRGGBB, or RRGGBBAA");
}
else {
return Err("Invalid hex pattern, expected RGB, RGBA, RRGGBB, or RRGGBBAA");
}
}
}
}