mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
reworks on setting nodes; Custom setting types are now tested to work!
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
Some checks are pending
Build Binaries / Build Windows (push) Waiting to run
Build Binaries / Build macOS (push) Waiting to run
Build Binaries / Build Android (64-bit) (push) Waiting to run
Build Binaries / Build Android (32-bit) (push) Waiting to run
Build Binaries / Publish (push) Blocked by required conditions
This commit is contained in:
parent
fdcdfbd30c
commit
81d5dc0cae
7 changed files with 361 additions and 493 deletions
|
@ -27,8 +27,8 @@ namespace geode {
|
|||
|
||||
protected:
|
||||
void init(std::string const& key, std::string const& modID);
|
||||
Result<> parseSharedProperties(std::string const& key, std::string const& modID, matjson::Value const& value, bool onlyNameAndDesc = false);
|
||||
void parseSharedProperties(std::string const& key, std::string const& modID, JsonExpectedValue& value, bool onlyNameAndDesc = false);
|
||||
Result<> parseBaseProperties(std::string const& key, std::string const& modID, matjson::Value const& value, bool onlyNameAndDesc = false);
|
||||
void parseBaseProperties(std::string const& key, std::string const& modID, JsonExpectedValue& value, bool onlyNameAndDesc = false);
|
||||
|
||||
/**
|
||||
* Mark that the value of this setting has changed. This should be
|
||||
|
@ -103,46 +103,124 @@ namespace geode {
|
|||
matjson::Value const& json
|
||||
)>;
|
||||
|
||||
namespace detail {
|
||||
template <class T, class V = T>
|
||||
class GeodeSettingBaseValueV3 : public SettingV3 {
|
||||
protected:
|
||||
virtual T& getValueMut() const = 0;
|
||||
|
||||
template <class D>
|
||||
void parseDefaultValue(JsonExpectedValue& json, D& defaultValue) {
|
||||
auto value = json.needs("default");
|
||||
// Check if this is a platform-specific default value
|
||||
if (value.isObject() && value.has(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH)) {
|
||||
value.needs(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH).into(defaultValue);
|
||||
}
|
||||
else {
|
||||
value.into(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
|
||||
virtual T getDefaultValue() const = 0;
|
||||
|
||||
T getValue() const {
|
||||
return this->getValueMut();
|
||||
}
|
||||
void setValue(V value) {
|
||||
this->getValueMut() = this->isValid(value) ? value : this->getDefaultValue();
|
||||
this->markChanged();
|
||||
}
|
||||
virtual Result<> isValid(V value) const = 0;
|
||||
|
||||
bool isDefaultValue() const override {
|
||||
return this->getValue() == this->getDefaultValue();
|
||||
}
|
||||
void reset() override {
|
||||
this->setValue(this->getDefaultValue());
|
||||
}
|
||||
/**
|
||||
* A helper class for creating a basic setting with a simple value.
|
||||
* Override the virtual function `isValid` to
|
||||
* @tparam T The type of the setting's value. This type must be JSON-
|
||||
* serializable and deserializable!
|
||||
* @tparam V The type used for the `setValue` function, if it differs from T
|
||||
*/
|
||||
template <class T, class V = T>
|
||||
class SettingBaseValueV3 : public SettingV3 {
|
||||
private:
|
||||
class Impl final {
|
||||
private:
|
||||
T defaultValue;
|
||||
T value;
|
||||
friend class SettingBaseValueV3;
|
||||
};
|
||||
}
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Parse shared value, including the default value for this setting
|
||||
* @param key The key of the setting
|
||||
* @param modID The ID of the mod this setting is being parsed for
|
||||
* @param json The current JSON checking instance being used. If you
|
||||
* aren't using Geode's JSON checking utilities, use the other overload
|
||||
* of this function
|
||||
*/
|
||||
void parseBaseProperties(std::string const& key, std::string const& modID, JsonExpectedValue& json) {
|
||||
SettingV3::parseBaseProperties(key, modID, json, false);
|
||||
auto root = json.needs("default");
|
||||
// Check if this is a platform-specific default value
|
||||
if (root.isObject() && root.has(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH)) {
|
||||
root.needs(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH).into(m_impl->defaultValue);
|
||||
}
|
||||
else {
|
||||
root.into(m_impl->defaultValue);
|
||||
}
|
||||
m_impl->value = m_impl->defaultValue;
|
||||
}
|
||||
/**
|
||||
* Parse shared value, including the default value for this setting
|
||||
* @param key The key of the setting
|
||||
* @param modID The ID of the mod this setting is being parsed for
|
||||
* @param json The JSON value. If you are using Geode's JSON checking
|
||||
* utilities (`checkJson` / `JsonExpectedValue`), you should use the
|
||||
* other overload directly!
|
||||
*/
|
||||
Result<> parseBaseProperties(std::string const& key, std::string const& modID, matjson::Value const& json) {
|
||||
auto root = checkJson(json, "SettingBaseValueV3");
|
||||
this->parseBaseProperties(key, modID, root);
|
||||
return root.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default value. This does not check that the value is
|
||||
* actually valid!
|
||||
*/
|
||||
void setDefaultValue(V value) {
|
||||
m_impl->defaultValue = value;
|
||||
}
|
||||
|
||||
public:
|
||||
SettingBaseValueV3() : m_impl(std::make_shared<Impl>()) {}
|
||||
|
||||
using ValueType = T;
|
||||
using ValueAssignType = V;
|
||||
|
||||
/**
|
||||
* Get the default value for this setting
|
||||
*/
|
||||
T getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value of this setting
|
||||
*/
|
||||
T getValue() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
/**
|
||||
* Set the value of this setting. This will broadcast a new
|
||||
* SettingChangedEventV3, letting any listeners now the value has changed
|
||||
* @param value The new value for the setting. If the value is not a
|
||||
* valid value for this setting (as determined by `isValue`), then the
|
||||
* setting's value is reset to the default value
|
||||
*/
|
||||
void setValue(V value) {
|
||||
m_impl->value = this->isValid(value) ? value : m_impl->defaultValue;
|
||||
this->markChanged();
|
||||
}
|
||||
/**
|
||||
* Check if a given value is valid for this setting. If not, an error
|
||||
* describing why the value isn't valid is returned
|
||||
*/
|
||||
virtual Result<> isValid(V value) const {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
bool isDefaultValue() const override {
|
||||
return m_impl->value == m_impl->defaultValue;
|
||||
}
|
||||
void reset() override {
|
||||
this->setValue(m_impl->defaultValue);
|
||||
}
|
||||
|
||||
bool load(matjson::Value const& json) override {
|
||||
if (json.template is<T>()) {
|
||||
m_impl->value = json.template as<T>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool save(matjson::Value& json) const override {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class GEODE_DLL TitleSettingV3 final : public SettingV3 {
|
||||
private:
|
||||
|
@ -196,14 +274,11 @@ namespace geode {
|
|||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL BoolSettingV3 final : public detail::GeodeSettingBaseValueV3<bool> {
|
||||
class GEODE_DLL BoolSettingV3 final : public SettingBaseValueV3<bool> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
bool& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -212,25 +287,19 @@ namespace geode {
|
|||
BoolSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<BoolSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
bool getDefaultValue() const override;
|
||||
Result<> isValid(bool value) const override;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL IntSettingV3 final : public detail::GeodeSettingBaseValueV3<int64_t> {
|
||||
class GEODE_DLL IntSettingV3 final : public SettingBaseValueV3<int64_t> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
int64_t& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -239,7 +308,6 @@ namespace geode {
|
|||
IntSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<IntSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
int64_t getDefaultValue() const override;
|
||||
Result<> isValid(int64_t value) const override;
|
||||
|
||||
std::optional<int64_t> getMinValue() const;
|
||||
|
@ -253,22 +321,17 @@ namespace geode {
|
|||
std::optional<int64_t> getSliderSnap() const;
|
||||
bool isInputEnabled() const;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL FloatSettingV3 final : public detail::GeodeSettingBaseValueV3<double> {
|
||||
class GEODE_DLL FloatSettingV3 final : public SettingBaseValueV3<double> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
double& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -277,7 +340,6 @@ namespace geode {
|
|||
FloatSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<FloatSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
double getDefaultValue() const override;
|
||||
Result<> isValid(double value) const override;
|
||||
|
||||
std::optional<double> getMinValue() const;
|
||||
|
@ -291,22 +353,17 @@ namespace geode {
|
|||
std::optional<double> getSliderSnap() const;
|
||||
bool isInputEnabled() const;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL StringSettingV3 final : public detail::GeodeSettingBaseValueV3<std::string, std::string_view> {
|
||||
class GEODE_DLL StringSettingV3 final : public SettingBaseValueV3<std::string, std::string_view> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
std::string& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -315,29 +372,23 @@ namespace geode {
|
|||
StringSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<StringSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
std::string getDefaultValue() const override;
|
||||
Result<> isValid(std::string_view value) const override;
|
||||
|
||||
std::optional<std::string> getRegexValidator() const;
|
||||
std::optional<std::string> getAllowedCharacters() const;
|
||||
std::optional<std::vector<std::string>> getEnumOptions() const;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL FileSettingV3 final : public detail::GeodeSettingBaseValueV3<std::filesystem::path, std::filesystem::path const&> {
|
||||
class GEODE_DLL FileSettingV3 final : public SettingBaseValueV3<std::filesystem::path, std::filesystem::path const&> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
std::filesystem::path& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -346,7 +397,6 @@ namespace geode {
|
|||
FileSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<FileSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
std::filesystem::path getDefaultValue() const override;
|
||||
Result<> isValid(std::filesystem::path const& value) const override;
|
||||
|
||||
bool isFolder() const;
|
||||
|
@ -354,22 +404,17 @@ namespace geode {
|
|||
|
||||
std::optional<std::vector<utils::file::FilePickOptions::Filter>> getFilters() const;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL Color3BSettingV3 final : public detail::GeodeSettingBaseValueV3<cocos2d::ccColor3B> {
|
||||
class GEODE_DLL Color3BSettingV3 final : public SettingBaseValueV3<cocos2d::ccColor3B> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
cocos2d::ccColor3B& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -378,25 +423,19 @@ namespace geode {
|
|||
Color3BSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<Color3BSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
cocos2d::ccColor3B getDefaultValue() const override;
|
||||
Result<> isValid(cocos2d::ccColor3B value) const override;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
std::optional<std::shared_ptr<SettingValue>> convertToLegacyValue() const override;
|
||||
};
|
||||
|
||||
class GEODE_DLL Color4BSettingV3 final : public detail::GeodeSettingBaseValueV3<cocos2d::ccColor4B> {
|
||||
class GEODE_DLL Color4BSettingV3 final : public SettingBaseValueV3<cocos2d::ccColor4B> {
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
cocos2d::ccColor4B& getValueMut() const override;
|
||||
|
||||
private:
|
||||
class PrivateMarker {};
|
||||
friend class SettingV3;
|
||||
|
@ -405,11 +444,8 @@ namespace geode {
|
|||
Color4BSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<Color4BSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
cocos2d::ccColor4B getDefaultValue() const override;
|
||||
Result<> isValid(cocos2d::ccColor4B value) const override;
|
||||
|
||||
bool load(matjson::Value const& json) override;
|
||||
bool save(matjson::Value& json) const override;
|
||||
SettingNodeV3* createNode(float width) override;
|
||||
|
||||
std::optional<Setting> convertToLegacy() const override;
|
||||
|
@ -426,13 +462,28 @@ namespace geode {
|
|||
protected:
|
||||
bool init(std::shared_ptr<SettingV3> setting, float width);
|
||||
|
||||
virtual void updateState();
|
||||
/**
|
||||
* Update the state of this setting node, bringing all inputs
|
||||
* up-to-date with the current value. Derivatives of `SettingNodeV3`
|
||||
* should set update the state (such as visibility, value, etc.) of all
|
||||
* its controls, except for the one that's passed as the `invoker`
|
||||
* argument. Derivatives should remember to **always call the base
|
||||
* class's `updateState` function**, as it updates the built-in title
|
||||
* label as well as the description and reset buttons!
|
||||
* @param invoker The button or other interactive element that caused
|
||||
* this state update. If that element is for example a text input, it
|
||||
* may wish to ignore the state update, as it itself is the source of
|
||||
* truth for the node's value at that moment. May be nullptr to mark
|
||||
* that no specific node requested this state update
|
||||
*/
|
||||
virtual void updateState(cocos2d::CCNode* invoker);
|
||||
|
||||
/**
|
||||
* Mark this setting as changed. This updates the UI for committing
|
||||
* the value
|
||||
* the value, as well as posts a `SettingNodeValueChangeEventV3`
|
||||
* @param invoker The node to be passed onto `updateState`
|
||||
*/
|
||||
void markChanged();
|
||||
void markChanged(cocos2d::CCNode* invoker);
|
||||
|
||||
/**
|
||||
* When the setting value is committed (aka can't be undone), this
|
||||
|
@ -453,17 +504,68 @@ namespace geode {
|
|||
|
||||
// Can be overridden by the setting itself
|
||||
// Can / should be used to do alternating BG
|
||||
void setBGColor(cocos2d::ccColor4B const& color);
|
||||
void setDefaultBGColor(cocos2d::ccColor4B color);
|
||||
|
||||
cocos2d::CCLabelBMFont* getNameLabel() const;
|
||||
cocos2d::CCMenu* getNameMenu() const;
|
||||
cocos2d::CCMenu* getButtonMenu() const;
|
||||
cocos2d::CCLayerColor* getBG() const;
|
||||
|
||||
void setContentSize(cocos2d::CCSize const& size) override;
|
||||
|
||||
std::shared_ptr<SettingV3> getSetting() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for creating `SettingNode`s for simple settings that
|
||||
* implement `SettingBaseValueV3`
|
||||
*/
|
||||
template <class S>
|
||||
class SettingValueNodeV3 : public SettingNodeV3 {
|
||||
protected:
|
||||
bool init(std::shared_ptr<S> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onCommit() override {
|
||||
this->getSetting()->setValue(this->getValue());
|
||||
}
|
||||
bool hasUncommittedChanges() const override {
|
||||
return this->getValue() != this->getSetting()->getValue();
|
||||
}
|
||||
bool hasNonDefaultValue() const override {
|
||||
return this->getValue() != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void onResetToDefault() override {
|
||||
this->setValue(this->getSetting()->getDefaultValue(), nullptr);
|
||||
}
|
||||
|
||||
virtual void onSetValue(typename S::ValueAssignType value) = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Get the **uncommitted** value for this node
|
||||
*/
|
||||
virtual typename S::ValueType getValue() const = 0;
|
||||
/**
|
||||
* Set the **uncommitted** value for this node
|
||||
* @param value The value to set
|
||||
* @param invoker The node that invoked this value change; see the docs
|
||||
* for `SettingNodeV3::updateState` to know more
|
||||
*/
|
||||
void setValue(typename S::ValueAssignType value, cocos2d::CCNode* invoker) {
|
||||
this->onSetValue(value);
|
||||
this->markChanged(invoker);
|
||||
}
|
||||
|
||||
std::shared_ptr<S> getSetting() const {
|
||||
return std::static_pointer_cast<S>(SettingNodeV3::getSetting());
|
||||
}
|
||||
};
|
||||
|
||||
class GEODE_DLL SettingChangedEventV3 final : public Event {
|
||||
private:
|
||||
class Impl;
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
"name": "Show Platform Console",
|
||||
"description": "Show the native console (if one exists). <cr>This setting is meant for developers</c>",
|
||||
"platforms": ["win", "mac"],
|
||||
"restart-required": true
|
||||
"requires-restart": true
|
||||
},
|
||||
"server-cache-size-limit": {
|
||||
"type": "int",
|
||||
|
|
|
@ -52,17 +52,25 @@ public:
|
|||
return Ok();
|
||||
}
|
||||
std::optional<SettingGenerator> find(std::string_view modID, std::string_view fullType) {
|
||||
auto full = std::string(
|
||||
fullType.starts_with("custom:") ?
|
||||
fullType.substr(fullType.find(':') + 1) :
|
||||
fullType
|
||||
);
|
||||
if (!full.find('/')) {
|
||||
full = fmt::format("{}/{}", modID, full);
|
||||
// Find custom settings via namespaced lookup
|
||||
if (fullType.starts_with("custom:")) {
|
||||
auto full = std::string(fullType.substr(fullType.find(':') + 1));
|
||||
// If there's no mod ID in the type name, use the current mod's ID
|
||||
if (full.find('/') == std::string_view::npos) {
|
||||
full = fmt::format("{}/{}", modID, full);
|
||||
}
|
||||
if (m_types.contains(full)) {
|
||||
return m_types.at(full);
|
||||
}
|
||||
}
|
||||
if (m_types.contains(full)) {
|
||||
return m_types.at(full);
|
||||
// Otherwise find a built-in setting
|
||||
else {
|
||||
auto full = std::string(fullType);
|
||||
if (m_types.contains(full)) {
|
||||
return m_types.at(full);
|
||||
}
|
||||
}
|
||||
// Return null if nothing was found
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
@ -171,12 +179,15 @@ Result<> ModSettingsManager::load(matjson::Value const& json) {
|
|||
auto root = checkJson(json, "Settings");
|
||||
for (auto const& [key, value] : root.properties()) {
|
||||
if (m_impl->settings.contains(key)) {
|
||||
auto& sett = m_impl->settings.at(key);
|
||||
if (!sett.v3) continue;
|
||||
try {
|
||||
if (!m_impl->settings.at(key).v3->load(value.json())) {
|
||||
if (!sett.v3->load(value.json())) {
|
||||
log::error("Unable to load setting '{}' for mod {}", key, m_impl->modID);
|
||||
}
|
||||
}
|
||||
catch(matjson::JsonException const& e) {
|
||||
// matjson::JsonException doesn't catch all possible json errors
|
||||
catch(std::exception const& e) {
|
||||
log::error("Unable to load setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
||||
if (!CCNode::init())
|
||||
return false;
|
||||
|
||||
// note: setting may be null due to UnresolvedCustomSettingNodeV3
|
||||
|
||||
m_impl = std::make_shared<Impl>();
|
||||
m_impl->setting = setting;
|
||||
|
@ -69,7 +71,7 @@ bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
|||
m_impl->nameMenu = CCMenu::create();
|
||||
m_impl->nameMenu->setContentWidth(width / 2 + 25);
|
||||
|
||||
m_impl->nameLabel = CCLabelBMFont::create(setting->getDisplayName().c_str(), "bigFont.fnt");
|
||||
m_impl->nameLabel = CCLabelBMFont::create(setting ? setting->getDisplayName().c_str() : "", "bigFont.fnt");
|
||||
m_impl->nameLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .4f)->setScalePriority(1));
|
||||
m_impl->nameMenu->addChild(m_impl->nameLabel);
|
||||
|
||||
|
@ -77,7 +79,7 @@ bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
|||
m_impl->errorLabel->setScale(.25f);
|
||||
this->addChildAtPosition(m_impl->errorLabel, Anchor::Left, ccp(10, -10), ccp(0, .5f));
|
||||
|
||||
if (setting->getDescription()) {
|
||||
if (setting && setting->getDescription()) {
|
||||
auto descSpr = CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png");
|
||||
descSpr->setScale(.5f);
|
||||
auto descBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -108,7 +110,7 @@ bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void SettingNodeV3::updateState() {
|
||||
void SettingNodeV3::updateState(CCNode* invoker) {
|
||||
m_impl->errorLabel->setVisible(false);
|
||||
|
||||
m_impl->nameLabel->setColor(this->hasUncommittedChanges() ? ccc3(17, 221, 0) : ccWHITE);
|
||||
|
@ -117,7 +119,7 @@ void SettingNodeV3::updateState() {
|
|||
m_impl->bg->setColor(to3B(m_impl->bgColor));
|
||||
m_impl->bg->setOpacity(m_impl->bgColor.a);
|
||||
|
||||
if (!m_impl->setting->shouldEnable()) {
|
||||
if (m_impl->setting && !m_impl->setting->shouldEnable()) {
|
||||
if (auto desc = m_impl->setting->getEnableIfDescription()) {
|
||||
m_impl->nameLabel->setColor(ccGRAY);
|
||||
m_impl->errorLabel->setVisible(true);
|
||||
|
@ -125,7 +127,7 @@ void SettingNodeV3::updateState() {
|
|||
m_impl->errorLabel->setString(desc->c_str());
|
||||
}
|
||||
}
|
||||
if (m_impl->setting->requiresRestart() && m_impl->committed) {
|
||||
if (m_impl->setting && m_impl->setting->requiresRestart() && m_impl->committed) {
|
||||
m_impl->errorLabel->setVisible(true);
|
||||
m_impl->errorLabel->setColor("mod-list-restart-required-label"_cc3b);
|
||||
m_impl->errorLabel->setString("Restart Required");
|
||||
|
@ -133,6 +135,7 @@ void SettingNodeV3::updateState() {
|
|||
m_impl->bg->setOpacity(75);
|
||||
}
|
||||
|
||||
m_impl->nameMenu->setContentWidth(this->getContentWidth() - m_impl->buttonMenu->getContentWidth() - 20);
|
||||
m_impl->nameMenu->updateLayout();
|
||||
}
|
||||
|
||||
|
@ -162,26 +165,27 @@ void SettingNodeV3::onReset(CCObject*) {
|
|||
);
|
||||
}
|
||||
|
||||
void SettingNodeV3::setBGColor(ccColor4B const& color) {
|
||||
void SettingNodeV3::setDefaultBGColor(ccColor4B color) {
|
||||
m_impl->bgColor = color;
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
}
|
||||
|
||||
void SettingNodeV3::markChanged() {
|
||||
this->updateState();
|
||||
void SettingNodeV3::markChanged(CCNode* invoker) {
|
||||
this->updateState(invoker);
|
||||
SettingNodeValueChangeEventV3(this, false).post();
|
||||
}
|
||||
void SettingNodeV3::commit() {
|
||||
this->onCommit();
|
||||
m_impl->committed = true;
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
SettingNodeValueChangeEventV3(this, true).post();
|
||||
}
|
||||
void SettingNodeV3::resetToDefault() {
|
||||
if (!m_impl->setting) return;
|
||||
m_impl->setting->reset();
|
||||
m_impl->committed = true;
|
||||
this->onResetToDefault();
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
SettingNodeValueChangeEventV3(this, false).post();
|
||||
}
|
||||
|
||||
|
@ -201,6 +205,9 @@ CCMenu* SettingNodeV3::getNameMenu() const {
|
|||
CCMenu* SettingNodeV3::getButtonMenu() const {
|
||||
return m_impl->buttonMenu;
|
||||
}
|
||||
CCLayerColor* SettingNodeV3::getBG() const {
|
||||
return m_impl->bg;
|
||||
}
|
||||
|
||||
std::shared_ptr<SettingV3> SettingNodeV3::getSetting() const {
|
||||
return m_impl->setting;
|
||||
|
@ -215,7 +222,7 @@ bool TitleSettingNodeV3::init(std::shared_ptr<TitleSettingV3> setting, float wid
|
|||
this->getNameLabel()->setFntFile("goldFont.fnt");
|
||||
this->getNameMenu()->updateLayout();
|
||||
this->setContentHeight(20);
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -247,12 +254,10 @@ TitleSettingNodeV3* TitleSettingNodeV3::create(std::shared_ptr<TitleSettingV3> s
|
|||
// BoolSettingNodeV3
|
||||
|
||||
bool BoolSettingNodeV3::init(std::shared_ptr<BoolSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
this->getButtonMenu()->setContentWidth(20);
|
||||
this->getNameMenu()->setContentWidth(width - 50);
|
||||
this->getNameMenu()->updateLayout();
|
||||
|
||||
m_toggle = CCMenuItemToggler::createWithStandardSprites(
|
||||
this, menu_selector(BoolSettingNodeV3::onToggle), .55f
|
||||
|
@ -265,13 +270,13 @@ bool BoolSettingNodeV3::init(std::shared_ptr<BoolSettingV3> setting, float width
|
|||
m_toggle->toggle(setting->getValue());
|
||||
this->getButtonMenu()->addChildAtPosition(m_toggle, Anchor::Right, ccp(-10, 0));
|
||||
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BoolSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
void BoolSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
m_toggle->setCascadeColorEnabled(true);
|
||||
m_toggle->setCascadeOpacityEnabled(true);
|
||||
|
@ -280,26 +285,16 @@ void BoolSettingNodeV3::updateState() {
|
|||
m_toggle->setOpacity(enable ? 255 : 155);
|
||||
}
|
||||
|
||||
void BoolSettingNodeV3::onCommit() {
|
||||
this->getSetting()->setValue(m_toggle->isToggled());
|
||||
}
|
||||
void BoolSettingNodeV3::onToggle(CCObject*) {
|
||||
m_toggle->toggle(!m_toggle->isToggled());
|
||||
this->markChanged();
|
||||
this->markChanged(m_toggle);
|
||||
}
|
||||
|
||||
bool BoolSettingNodeV3::hasUncommittedChanges() const {
|
||||
return m_toggle->isToggled() != this->getSetting()->getValue();
|
||||
bool BoolSettingNodeV3::getValue() const {
|
||||
return m_toggle->isToggled();
|
||||
}
|
||||
bool BoolSettingNodeV3::hasNonDefaultValue() const {
|
||||
return m_toggle->isToggled() != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void BoolSettingNodeV3::onResetToDefault() {
|
||||
m_toggle->toggle(this->getSetting()->getDefaultValue());
|
||||
}
|
||||
|
||||
std::shared_ptr<BoolSettingV3> BoolSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<BoolSettingV3>(SettingNodeV3::getSetting());
|
||||
void BoolSettingNodeV3::onSetValue(bool value) {
|
||||
m_toggle->toggle(value);
|
||||
}
|
||||
|
||||
BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr<BoolSettingV3> setting, float width) {
|
||||
|
@ -315,12 +310,12 @@ BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr<BoolSettingV3> sett
|
|||
// StringSettingNodeV3
|
||||
|
||||
bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_input = TextInput::create(setting->getEnumOptions() ? width / 2 - 50 : width / 2, "Text");
|
||||
m_input->setCallback([this](auto const&) {
|
||||
this->markChanged();
|
||||
this->markChanged(m_input);
|
||||
});
|
||||
m_input->setScale(.7f);
|
||||
m_input->setString(this->getSetting()->getValue());
|
||||
|
@ -350,13 +345,13 @@ bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float w
|
|||
this->getButtonMenu()->addChildAtPosition(arrowRightBtn, Anchor::Right, ccp(-5, 0));
|
||||
}
|
||||
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StringSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
void StringSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
if (!this->getSetting()->getEnumOptions()) {
|
||||
m_input->setEnabled(enable);
|
||||
|
@ -379,24 +374,14 @@ void StringSettingNodeV3::onArrow(CCObject* sender) {
|
|||
index = index > 0 ? index - 1 : options.size() - 1;
|
||||
}
|
||||
m_input->setString(options.at(index));
|
||||
this->updateState();
|
||||
this->updateState(static_cast<CCNode*>(sender));
|
||||
}
|
||||
|
||||
void StringSettingNodeV3::onCommit() {
|
||||
this->getSetting()->setValue(m_input->getString());
|
||||
std::string StringSettingNodeV3::getValue() const {
|
||||
return m_input->getString();
|
||||
}
|
||||
bool StringSettingNodeV3::hasUncommittedChanges() const {
|
||||
return m_input->getString() != this->getSetting()->getValue();
|
||||
}
|
||||
bool StringSettingNodeV3::hasNonDefaultValue() const {
|
||||
return m_input->getString() != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void StringSettingNodeV3::onResetToDefault() {
|
||||
m_input->setString(this->getSetting()->getDefaultValue());
|
||||
}
|
||||
|
||||
std::shared_ptr<StringSettingV3> StringSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<StringSettingV3>(SettingNodeV3::getSetting());
|
||||
void StringSettingNodeV3::onSetValue(std::string_view value) {
|
||||
m_input->setString(std::string(value));
|
||||
}
|
||||
|
||||
StringSettingNodeV3* StringSettingNodeV3::create(std::shared_ptr<StringSettingV3> setting, float width) {
|
||||
|
@ -412,7 +397,7 @@ StringSettingNodeV3* StringSettingNodeV3::create(std::shared_ptr<StringSettingV3
|
|||
// FileSettingNodeV3
|
||||
|
||||
bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_path = setting->getValue();
|
||||
|
@ -437,13 +422,13 @@ bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width
|
|||
);
|
||||
this->getButtonMenu()->addChildAtPosition(m_selectBtn, Anchor::Right, ccp(-5, 0));
|
||||
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
void FileSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
m_fileIcon->setDisplayFrame(CCSpriteFrameCache::get()->spriteFrameByName(
|
||||
this->getSetting()->isFolder() ? "folderIcon_001.png" : "file.png"_spr
|
||||
));
|
||||
|
@ -474,7 +459,7 @@ void FileSettingNodeV3::onPickFile(CCObject*) {
|
|||
}
|
||||
if (value->isOk()) {
|
||||
m_path = value->unwrap().string();
|
||||
this->markChanged();
|
||||
this->markChanged(nullptr);
|
||||
}
|
||||
else {
|
||||
FLAlertLayer::create(
|
||||
|
@ -497,21 +482,11 @@ void FileSettingNodeV3::onPickFile(CCObject*) {
|
|||
));
|
||||
}
|
||||
|
||||
void FileSettingNodeV3::onCommit() {
|
||||
this->getSetting()->setValue(m_path);
|
||||
std::filesystem::path FileSettingNodeV3::getValue() const {
|
||||
return m_path;
|
||||
}
|
||||
bool FileSettingNodeV3::hasUncommittedChanges() const {
|
||||
return m_path != this->getSetting()->getValue();
|
||||
}
|
||||
bool FileSettingNodeV3::hasNonDefaultValue() const {
|
||||
return m_path != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void FileSettingNodeV3::onResetToDefault() {
|
||||
m_path = this->getSetting()->getDefaultValue();
|
||||
}
|
||||
|
||||
std::shared_ptr<FileSettingV3> FileSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<FileSettingV3>(SettingNodeV3::getSetting());
|
||||
void FileSettingNodeV3::onSetValue(std::filesystem::path const& value) {
|
||||
m_path = value;
|
||||
}
|
||||
|
||||
FileSettingNodeV3* FileSettingNodeV3::create(std::shared_ptr<FileSettingV3> setting, float width) {
|
||||
|
@ -527,7 +502,7 @@ FileSettingNodeV3* FileSettingNodeV3::create(std::shared_ptr<FileSettingV3> sett
|
|||
// Color3BSettingNodeV3
|
||||
|
||||
bool Color3BSettingNodeV3::init(std::shared_ptr<Color3BSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_value = setting->getValue();
|
||||
|
@ -540,13 +515,13 @@ bool Color3BSettingNodeV3::init(std::shared_ptr<Color3BSettingV3> setting, float
|
|||
);
|
||||
this->getButtonMenu()->addChildAtPosition(m_colorBtn, Anchor::Right, ccp(-10, 0));
|
||||
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Color3BSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
void Color3BSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
m_colorSprite->setColor(m_value);
|
||||
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
|
@ -561,24 +536,14 @@ void Color3BSettingNodeV3::onSelectColor(CCObject*) {
|
|||
}
|
||||
void Color3BSettingNodeV3::updateColor(ccColor4B const& color) {
|
||||
m_value = to3B(color);
|
||||
this->markChanged();
|
||||
this->markChanged(nullptr);
|
||||
}
|
||||
|
||||
void Color3BSettingNodeV3::onCommit() {
|
||||
this->getSetting()->setValue(m_value);
|
||||
ccColor3B Color3BSettingNodeV3::getValue() const {
|
||||
return m_value;
|
||||
}
|
||||
bool Color3BSettingNodeV3::hasUncommittedChanges() const {
|
||||
return m_value != this->getSetting()->getValue();
|
||||
}
|
||||
bool Color3BSettingNodeV3::hasNonDefaultValue() const {
|
||||
return m_value != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void Color3BSettingNodeV3::onResetToDefault() {
|
||||
m_value = this->getSetting()->getDefaultValue();
|
||||
}
|
||||
|
||||
std::shared_ptr<Color3BSettingV3> Color3BSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<Color3BSettingV3>(SettingNodeV3::getSetting());
|
||||
void Color3BSettingNodeV3::onSetValue(ccColor3B value) {
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
Color3BSettingNodeV3* Color3BSettingNodeV3::create(std::shared_ptr<Color3BSettingV3> setting, float width) {
|
||||
|
@ -594,7 +559,7 @@ Color3BSettingNodeV3* Color3BSettingNodeV3::create(std::shared_ptr<Color3BSettin
|
|||
// Color4BSettingNodeV3
|
||||
|
||||
bool Color4BSettingNodeV3::init(std::shared_ptr<Color4BSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_value = setting->getValue();
|
||||
|
@ -607,13 +572,13 @@ bool Color4BSettingNodeV3::init(std::shared_ptr<Color4BSettingV3> setting, float
|
|||
);
|
||||
this->getButtonMenu()->addChildAtPosition(m_colorBtn, Anchor::Right, ccp(-10, 0));
|
||||
|
||||
this->updateState();
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Color4BSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
void Color4BSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
m_colorSprite->setColor(to3B(m_value));
|
||||
m_colorSprite->updateOpacity(m_value.a / 255.f);
|
||||
|
||||
|
@ -629,24 +594,14 @@ void Color4BSettingNodeV3::onSelectColor(CCObject*) {
|
|||
}
|
||||
void Color4BSettingNodeV3::updateColor(ccColor4B const& color) {
|
||||
m_value = color;
|
||||
this->markChanged();
|
||||
this->markChanged(nullptr);
|
||||
}
|
||||
|
||||
void Color4BSettingNodeV3::onCommit() {
|
||||
this->getSetting()->setValue(m_value);
|
||||
ccColor4B Color4BSettingNodeV3::getValue() const {
|
||||
return m_value;
|
||||
}
|
||||
bool Color4BSettingNodeV3::hasUncommittedChanges() const {
|
||||
return m_value != this->getSetting()->getValue();
|
||||
}
|
||||
bool Color4BSettingNodeV3::hasNonDefaultValue() const {
|
||||
return m_value != this->getSetting()->getDefaultValue();
|
||||
}
|
||||
void Color4BSettingNodeV3::onResetToDefault() {
|
||||
m_value = this->getSetting()->getDefaultValue();
|
||||
}
|
||||
|
||||
std::shared_ptr<Color4BSettingV3> Color4BSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<Color4BSettingV3>(SettingNodeV3::getSetting());
|
||||
void Color4BSettingNodeV3::onSetValue(ccColor4B value) {
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
Color4BSettingNodeV3* Color4BSettingNodeV3::create(std::shared_ptr<Color4BSettingV3> setting, float width) {
|
||||
|
@ -661,22 +616,29 @@ Color4BSettingNodeV3* Color4BSettingNodeV3::create(std::shared_ptr<Color4BSettin
|
|||
|
||||
// UnresolvedCustomSettingNodeV3
|
||||
|
||||
bool UnresolvedCustomSettingNodeV3::init(std::shared_ptr<LegacyCustomSettingV3> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
bool UnresolvedCustomSettingNodeV3::init(std::string_view key, float width) {
|
||||
if (!SettingNodeV3::init(nullptr, width))
|
||||
return false;
|
||||
|
||||
this->setContentHeight(30);
|
||||
|
||||
auto label = CCLabelBMFont::create(
|
||||
fmt::format("Missing setting '{}'", setting->getKey()).c_str(),
|
||||
fmt::format("Missing setting '{}'", key).c_str(),
|
||||
"bigFont.fnt"
|
||||
);
|
||||
label->limitLabelWidth(width - m_obContentSize.height, .5f, .1f);
|
||||
this->addChildAtPosition(label, Anchor::Left, ccp(m_obContentSize.height / 2, 0));
|
||||
|
||||
label->setColor("mod-list-errors-found-2"_cc3b);
|
||||
label->limitLabelWidth(width - m_obContentSize.height, .3f, .1f);
|
||||
this->addChildAtPosition(label, Anchor::Left, ccp(m_obContentSize.height / 2, 0), ccp(0, .5f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UnresolvedCustomSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
this->getBG()->setColor("mod-list-errors-found"_cc3b);
|
||||
this->getBG()->setOpacity(75);
|
||||
}
|
||||
|
||||
void UnresolvedCustomSettingNodeV3::onCommit() {}
|
||||
|
||||
bool UnresolvedCustomSettingNodeV3::hasUncommittedChanges() const {
|
||||
|
@ -687,13 +649,9 @@ bool UnresolvedCustomSettingNodeV3::hasNonDefaultValue() const {
|
|||
}
|
||||
void UnresolvedCustomSettingNodeV3::onResetToDefault() {}
|
||||
|
||||
std::shared_ptr<LegacyCustomSettingV3> UnresolvedCustomSettingNodeV3::getSetting() const {
|
||||
return std::static_pointer_cast<LegacyCustomSettingV3>(SettingNodeV3::getSetting());
|
||||
}
|
||||
|
||||
UnresolvedCustomSettingNodeV3* UnresolvedCustomSettingNodeV3::create(std::shared_ptr<LegacyCustomSettingV3> setting, float width) {
|
||||
UnresolvedCustomSettingNodeV3* UnresolvedCustomSettingNodeV3::create(std::string_view key, float width) {
|
||||
auto ret = new UnresolvedCustomSettingNodeV3();
|
||||
if (ret && ret->init(setting, width)) {
|
||||
if (ret && ret->init(key, width)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -27,31 +27,26 @@ public:
|
|||
std::shared_ptr<TitleSettingV3> getSetting() const;
|
||||
};
|
||||
|
||||
class BoolSettingNodeV3 : public SettingNodeV3 {
|
||||
class BoolSettingNodeV3 : public SettingValueNodeV3<BoolSettingV3> {
|
||||
protected:
|
||||
CCMenuItemToggler* m_toggle;
|
||||
|
||||
bool init(std::shared_ptr<BoolSettingV3> setting, float width);
|
||||
|
||||
void updateState() override;
|
||||
|
||||
void onCommit() override;
|
||||
void updateState(CCNode* invoker) override;
|
||||
void onToggle(CCObject*);
|
||||
|
||||
public:
|
||||
static BoolSettingNodeV3* create(std::shared_ptr<BoolSettingV3> setting, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
bool getValue() const override;
|
||||
void onSetValue(bool value) override;
|
||||
|
||||
std::shared_ptr<BoolSettingV3> getSetting() const;
|
||||
static BoolSettingNodeV3* create(std::shared_ptr<BoolSettingV3> setting, float width);
|
||||
};
|
||||
|
||||
template <class S>
|
||||
class NumberSettingNodeV3 : public SettingNodeV3 {
|
||||
class NumberSettingNodeV3 : public SettingValueNodeV3<S> {
|
||||
protected:
|
||||
using ValueType = typename S::ValueType;
|
||||
using ValueAssignType = typename S::ValueAssignType;
|
||||
|
||||
TextInput* m_input;
|
||||
Slider* m_slider;
|
||||
|
@ -82,7 +77,7 @@ protected:
|
|||
}
|
||||
|
||||
bool init(std::shared_ptr<S> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
if (!SettingValueNodeV3<S>::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_bigArrowLeftBtnSpr = CCSprite::create();
|
||||
|
@ -115,7 +110,7 @@ protected:
|
|||
m_input = TextInput::create(this->getButtonMenu()->getContentWidth() - 40, "Num");
|
||||
m_input->setScale(.7f);
|
||||
m_input->setCallback([this](auto const&) {
|
||||
this->markChanged();
|
||||
this->markChanged(m_input);
|
||||
});
|
||||
if (!setting->isInputEnabled()) {
|
||||
m_input->getBGSprite()->setVisible(false);
|
||||
|
@ -164,21 +159,21 @@ protected:
|
|||
this->getButtonMenu()->addChildAtPosition(m_slider, Anchor::Center, ccp(0, -20), ccp(0, 0));
|
||||
}
|
||||
|
||||
this->setCurrentValue(setting->getValue());
|
||||
this->updateState();
|
||||
this->setValue(setting->getValue(), nullptr);
|
||||
this->updateState(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateState() override {
|
||||
SettingNodeV3::updateState();
|
||||
void updateState(CCNode* invoker) override {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
if (this->getSetting()->isInputEnabled()) {
|
||||
m_input->setEnabled(enable);
|
||||
}
|
||||
|
||||
auto min = this->getSetting()->getMinValue();
|
||||
auto enableLeft = enable && (!min || this->getCurrentValue() > *min);
|
||||
auto enableLeft = enable && (!min || this->getValue() > *min);
|
||||
m_arrowLeftBtn->setEnabled(enableLeft);
|
||||
m_bigArrowLeftBtn->setEnabled(enableLeft);
|
||||
m_arrowLeftBtnSpr->setOpacity(enableLeft ? 255 : 155);
|
||||
|
@ -187,7 +182,7 @@ protected:
|
|||
m_bigArrowLeftBtnSpr->setColor(enableLeft ? ccWHITE : ccGRAY);
|
||||
|
||||
auto max = this->getSetting()->getMaxValue();
|
||||
auto enableRight = enable && (!max || this->getCurrentValue() < *max);
|
||||
auto enableRight = enable && (!max || this->getValue() < *max);
|
||||
m_arrowRightBtn->setEnabled(enableRight);
|
||||
m_bigArrowRightBtn->setEnabled(enableRight);
|
||||
m_arrowRightBtnSpr->setOpacity(enableRight ? 255 : 155);
|
||||
|
@ -196,7 +191,7 @@ protected:
|
|||
m_bigArrowRightBtnSpr->setColor(enableRight ? ccWHITE : ccGRAY);
|
||||
|
||||
if (m_slider) {
|
||||
m_slider->m_touchLogic->m_thumb->setValue(this->valueToSlider(this->getCurrentValue()));
|
||||
m_slider->m_touchLogic->m_thumb->setValue(this->valueToSlider(this->getValue()));
|
||||
m_slider->updateBar();
|
||||
m_slider->m_sliderBar->setColor(enable ? ccWHITE : ccGRAY);
|
||||
m_slider->m_touchLogic->m_thumb->setColor(enable ? ccWHITE : ccGRAY);
|
||||
|
@ -204,11 +199,8 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void onCommit() override {
|
||||
this->getSetting()->setValue(this->getCurrentValue());
|
||||
}
|
||||
void onArrow(CCObject* sender) {
|
||||
auto value = this->getCurrentValue() + static_cast<ObjWrapper<ValueType>*>(
|
||||
auto value = this->getValue() + static_cast<ObjWrapper<ValueType>*>(
|
||||
static_cast<CCNode*>(sender)->getUserObject()
|
||||
)->getValue();
|
||||
if (auto min = this->getSetting()->getMinValue()) {
|
||||
|
@ -217,19 +209,18 @@ protected:
|
|||
if (auto max = this->getSetting()->getMaxValue()) {
|
||||
value = std::min(*max, value);
|
||||
}
|
||||
this->setCurrentValue(value);
|
||||
this->setValue(value, static_cast<CCNode*>(sender));
|
||||
}
|
||||
void onSlider(CCObject*) {
|
||||
this->setCurrentValue(this->valueFromSlider(m_slider->m_touchLogic->m_thumb->getValue()));
|
||||
this->setValue(this->valueFromSlider(m_slider->m_touchLogic->m_thumb->getValue()), m_slider);
|
||||
}
|
||||
|
||||
ValueType getCurrentValue() const {
|
||||
ValueType getValue() const override {
|
||||
return numFromString<ValueType>(m_input->getString())
|
||||
.value_or(this->getSetting()->getDefaultValue());
|
||||
}
|
||||
void setCurrentValue(ValueType value) {
|
||||
void onSetValue(ValueAssignType value) override {
|
||||
m_input->setString(numToString(value));
|
||||
this->markChanged();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -242,50 +233,29 @@ public:
|
|||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool hasUncommittedChanges() const override {
|
||||
return this->getSetting()->getValue() != this->getCurrentValue();
|
||||
}
|
||||
bool hasNonDefaultValue() const override {
|
||||
return this->getSetting()->getDefaultValue() != this->getCurrentValue();
|
||||
}
|
||||
void onResetToDefault() override {
|
||||
this->setCurrentValue(this->getSetting()->getDefaultValue());
|
||||
}
|
||||
|
||||
std::shared_ptr<S> getSetting() const {
|
||||
return std::static_pointer_cast<S>(SettingNodeV3::getSetting());
|
||||
}
|
||||
};
|
||||
|
||||
using IntSettingNodeV3 = NumberSettingNodeV3<IntSettingV3>;
|
||||
using FloatSettingNodeV3 = NumberSettingNodeV3<FloatSettingV3>;
|
||||
|
||||
class StringSettingNodeV3 : public SettingNodeV3 {
|
||||
class StringSettingNodeV3 : public SettingValueNodeV3<StringSettingV3> {
|
||||
protected:
|
||||
TextInput* m_input;
|
||||
CCSprite* m_arrowLeftSpr = nullptr;
|
||||
CCSprite* m_arrowRightSpr = nullptr;
|
||||
|
||||
bool init(std::shared_ptr<StringSettingV3> setting, float width);
|
||||
|
||||
void updateState() override;
|
||||
|
||||
void updateState(CCNode* invoker) override;
|
||||
void onArrow(CCObject* sender);
|
||||
|
||||
void onCommit() override;
|
||||
|
||||
public:
|
||||
static StringSettingNodeV3* create(std::shared_ptr<StringSettingV3> setting, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
|
||||
std::shared_ptr<StringSettingV3> getSetting() const;
|
||||
std::string getValue() const override;
|
||||
void onSetValue(std::string_view value) override;
|
||||
};
|
||||
|
||||
class FileSettingNodeV3 : public SettingNodeV3 {
|
||||
class FileSettingNodeV3 : public SettingValueNodeV3<FileSettingV3> {
|
||||
protected:
|
||||
CCSprite* m_fileIcon;
|
||||
std::filesystem::path m_path;
|
||||
|
@ -295,84 +265,66 @@ protected:
|
|||
CCSprite* m_selectBtnSpr;
|
||||
|
||||
bool init(std::shared_ptr<FileSettingV3> setting, float width);
|
||||
|
||||
void updateState() override;
|
||||
|
||||
void onCommit() override;
|
||||
void updateState(CCNode* invoker) override;
|
||||
void onPickFile(CCObject*);
|
||||
|
||||
public:
|
||||
static FileSettingNodeV3* create(std::shared_ptr<FileSettingV3> setting, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
|
||||
std::shared_ptr<FileSettingV3> getSetting() const;
|
||||
std::filesystem::path getValue() const override;
|
||||
void onSetValue(std::filesystem::path const& value) override;
|
||||
};
|
||||
|
||||
class Color3BSettingNodeV3 : public SettingNodeV3, public ColorPickPopupDelegate {
|
||||
class Color3BSettingNodeV3 : public SettingValueNodeV3<Color3BSettingV3>, public ColorPickPopupDelegate {
|
||||
protected:
|
||||
ccColor3B m_value;
|
||||
CCMenuItemSpriteExtra* m_colorBtn;
|
||||
ColorChannelSprite* m_colorSprite;
|
||||
|
||||
bool init(std::shared_ptr<Color3BSettingV3> setting, float width);
|
||||
|
||||
void updateState() override;
|
||||
|
||||
void onCommit() override;
|
||||
void updateState(CCNode* invoker) override;
|
||||
void onSelectColor(CCObject*);
|
||||
void updateColor(ccColor4B const& color) override;
|
||||
|
||||
public:
|
||||
static Color3BSettingNodeV3* create(std::shared_ptr<Color3BSettingV3> setting, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
|
||||
std::shared_ptr<Color3BSettingV3> getSetting() const;
|
||||
ccColor3B getValue() const override;
|
||||
void onSetValue(ccColor3B value) override;
|
||||
};
|
||||
|
||||
class Color4BSettingNodeV3 : public SettingNodeV3, public ColorPickPopupDelegate {
|
||||
class Color4BSettingNodeV3 : public SettingValueNodeV3<Color4BSettingV3>, public ColorPickPopupDelegate {
|
||||
protected:
|
||||
ccColor4B m_value;
|
||||
CCMenuItemSpriteExtra* m_colorBtn;
|
||||
ColorChannelSprite* m_colorSprite;
|
||||
|
||||
bool init(std::shared_ptr<Color4BSettingV3> setting, float width);
|
||||
|
||||
void updateState() override;
|
||||
|
||||
void onCommit() override;
|
||||
void updateState(CCNode* invoker) override;
|
||||
void onSelectColor(CCObject*);
|
||||
void updateColor(ccColor4B const& color) override;
|
||||
|
||||
public:
|
||||
static Color4BSettingNodeV3* create(std::shared_ptr<Color4BSettingV3> setting, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
|
||||
std::shared_ptr<Color4BSettingV3> getSetting() const;
|
||||
ccColor4B getValue() const override;
|
||||
void onSetValue(ccColor4B value) override;
|
||||
};
|
||||
|
||||
class UnresolvedCustomSettingNodeV3 : public SettingNodeV3 {
|
||||
protected:
|
||||
bool init(std::shared_ptr<LegacyCustomSettingV3> setting, float width);
|
||||
bool init(std::string_view key, float width);
|
||||
|
||||
void updateState(CCNode* invoker) override;
|
||||
|
||||
void onCommit() override;
|
||||
|
||||
public:
|
||||
static UnresolvedCustomSettingNodeV3* create(std::shared_ptr<LegacyCustomSettingV3> setting, float width);
|
||||
static UnresolvedCustomSettingNodeV3* create(std::string_view key, float width);
|
||||
|
||||
bool hasUncommittedChanges() const override;
|
||||
bool hasNonDefaultValue() const override;
|
||||
void onResetToDefault() override;
|
||||
|
||||
std::shared_ptr<LegacyCustomSettingV3> getSetting() const;
|
||||
};
|
||||
|
||||
// If these classes do get exposed in headers,
|
||||
|
|
|
@ -471,12 +471,12 @@ public:
|
|||
SettingV3::SettingV3() : m_impl(std::make_shared<GeodeImpl>()) {}
|
||||
SettingV3::~SettingV3() = default;
|
||||
|
||||
Result<> SettingV3::parseSharedProperties(std::string const& key, std::string const& modID, matjson::Value const& value, bool onlyNameAndDesc) {
|
||||
Result<> SettingV3::parseBaseProperties(std::string const& key, std::string const& modID, matjson::Value const& value, bool onlyNameAndDesc) {
|
||||
auto json = checkJson(value, "SettingV3");
|
||||
this->parseSharedProperties(key, modID, json, onlyNameAndDesc);
|
||||
this->parseBaseProperties(key, modID, json, onlyNameAndDesc);
|
||||
return json.ok();
|
||||
}
|
||||
void SettingV3::parseSharedProperties(std::string const& key, std::string const& modID, JsonExpectedValue& value, bool onlyNameAndDesc) {
|
||||
void SettingV3::parseBaseProperties(std::string const& key, std::string const& modID, JsonExpectedValue& value, bool onlyNameAndDesc) {
|
||||
this->init(key, modID);
|
||||
value.needs("type");
|
||||
value.has("platforms");
|
||||
|
@ -573,7 +573,7 @@ TitleSettingV3::TitleSettingV3(PrivateMarker) : m_impl(std::make_shared<Impl>())
|
|||
Result<std::shared_ptr<TitleSettingV3>> TitleSettingV3::parse(std::string const& key, std::string const& modID, matjson::Value const& json) {
|
||||
auto ret = std::make_shared<TitleSettingV3>(PrivateMarker());
|
||||
auto root = checkJson(json, "TitleSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root, true);
|
||||
ret->parseBaseProperties(key, modID, root, true);
|
||||
root.checkUnknownKeys();
|
||||
return root.ok(ret);
|
||||
}
|
||||
|
@ -628,9 +628,7 @@ SettingNodeV3* LegacyCustomSettingV3::createNode(float width) {
|
|||
std::static_pointer_cast<LegacyCustomSettingV3>(shared_from_this()), width
|
||||
);
|
||||
}
|
||||
return UnresolvedCustomSettingNodeV3::create(
|
||||
std::static_pointer_cast<LegacyCustomSettingV3>(shared_from_this()), width
|
||||
);
|
||||
return UnresolvedCustomSettingNodeV3::create(this->getKey(), width);
|
||||
}
|
||||
|
||||
bool LegacyCustomSettingV3::isDefaultValue() const {
|
||||
|
@ -649,45 +647,22 @@ std::optional<std::shared_ptr<SettingValue>> LegacyCustomSettingV3::convertToLeg
|
|||
|
||||
class BoolSettingV3::Impl final {
|
||||
public:
|
||||
bool value;
|
||||
bool defaultValue;
|
||||
};
|
||||
|
||||
BoolSettingV3::BoolSettingV3(PrivateMarker) : m_impl(std::make_shared<Impl>()) {}
|
||||
|
||||
Result<std::shared_ptr<BoolSettingV3>> BoolSettingV3::parse(std::string const& key, std::string const& modID, matjson::Value const& json) {
|
||||
auto ret = std::make_shared<BoolSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "BoolSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
root.checkUnknownKeys();
|
||||
return root.ok(ret);
|
||||
}
|
||||
|
||||
bool& BoolSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
bool BoolSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> BoolSettingV3::isValid(bool value) const {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
bool BoolSettingV3::load(matjson::Value const& json) {
|
||||
if (json.is_bool()) {
|
||||
m_impl->value = json.as_bool();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool BoolSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* BoolSettingV3::createNode(float width) {
|
||||
return BoolSettingNodeV3::create(
|
||||
std::static_pointer_cast<BoolSettingV3>(shared_from_this()), width
|
||||
|
@ -707,8 +682,6 @@ std::optional<std::shared_ptr<SettingValue>> BoolSettingV3::convertToLegacyValue
|
|||
|
||||
class IntSettingV3::Impl final {
|
||||
public:
|
||||
int64_t value;
|
||||
int64_t defaultValue;
|
||||
std::optional<int64_t> minValue;
|
||||
std::optional<int64_t> maxValue;
|
||||
|
||||
|
@ -726,9 +699,7 @@ Result<std::shared_ptr<IntSettingV3>> IntSettingV3::parse(std::string const& key
|
|||
auto ret = std::make_shared<IntSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "IntSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
|
||||
root.has("min").into(ret->m_impl->minValue);
|
||||
root.has("max").into(ret->m_impl->maxValue);
|
||||
|
@ -773,12 +744,6 @@ Result<std::shared_ptr<IntSettingV3>> IntSettingV3::parse(std::string const& key
|
|||
|
||||
IntSettingV3::IntSettingV3(PrivateMarker) : m_impl(std::make_shared<Impl>()) {}
|
||||
|
||||
int64_t& IntSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
int64_t IntSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> IntSettingV3::isValid(int64_t value) const {
|
||||
if (m_impl->minValue && value < *m_impl->minValue) {
|
||||
return Err("Value must be at least {}", *m_impl->minValue);
|
||||
|
@ -818,17 +783,6 @@ bool IntSettingV3::isInputEnabled() const {
|
|||
return m_impl->controls.textInputEnabled;
|
||||
}
|
||||
|
||||
bool IntSettingV3::load(matjson::Value const& json) {
|
||||
if (json.is_number()) {
|
||||
m_impl->value = json.as_int();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool IntSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* IntSettingV3::createNode(float width) {
|
||||
return IntSettingNodeV3::create(
|
||||
std::static_pointer_cast<IntSettingV3>(shared_from_this()), width
|
||||
|
@ -859,8 +813,6 @@ std::optional<std::shared_ptr<SettingValue>> IntSettingV3::convertToLegacyValue(
|
|||
|
||||
class FloatSettingV3::Impl final {
|
||||
public:
|
||||
double value;
|
||||
double defaultValue;
|
||||
std::optional<double> minValue;
|
||||
std::optional<double> maxValue;
|
||||
|
||||
|
@ -880,9 +832,7 @@ Result<std::shared_ptr<FloatSettingV3>> FloatSettingV3::parse(std::string const&
|
|||
auto ret = std::make_shared<FloatSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "FloatSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
|
||||
root.has("min").into(ret->m_impl->minValue);
|
||||
root.has("max").into(ret->m_impl->maxValue);
|
||||
|
@ -923,12 +873,6 @@ Result<std::shared_ptr<FloatSettingV3>> FloatSettingV3::parse(std::string const&
|
|||
return root.ok(ret);
|
||||
}
|
||||
|
||||
double& FloatSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
double FloatSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> FloatSettingV3::isValid(double value) const {
|
||||
if (m_impl->minValue && value < *m_impl->minValue) {
|
||||
return Err("Value must be at least {}", *m_impl->minValue);
|
||||
|
@ -968,17 +912,6 @@ bool FloatSettingV3::isInputEnabled() const {
|
|||
return m_impl->controls.textInputEnabled;
|
||||
}
|
||||
|
||||
bool FloatSettingV3::load(matjson::Value const& json) {
|
||||
if (json.is_number()) {
|
||||
m_impl->value = json.as_double();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool FloatSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* FloatSettingV3::createNode(float width) {
|
||||
return FloatSettingNodeV3::create(
|
||||
std::static_pointer_cast<FloatSettingV3>(shared_from_this()), width
|
||||
|
@ -1009,8 +942,6 @@ std::optional<std::shared_ptr<SettingValue>> FloatSettingV3::convertToLegacyValu
|
|||
|
||||
class StringSettingV3::Impl final {
|
||||
public:
|
||||
std::string value;
|
||||
std::string defaultValue;
|
||||
std::optional<std::string> match;
|
||||
std::optional<std::string> filter;
|
||||
std::optional<std::vector<std::string>> oneOf;
|
||||
|
@ -1022,9 +953,7 @@ Result<std::shared_ptr<StringSettingV3>> StringSettingV3::parse(std::string cons
|
|||
auto ret = std::make_shared<StringSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "StringSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
|
||||
root.has("match").into(ret->m_impl->match);
|
||||
root.has("filter").into(ret->m_impl->filter);
|
||||
|
@ -1037,12 +966,6 @@ Result<std::shared_ptr<StringSettingV3>> StringSettingV3::parse(std::string cons
|
|||
return root.ok(ret);
|
||||
}
|
||||
|
||||
std::string& StringSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
std::string StringSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> StringSettingV3::isValid(std::string_view value) const {
|
||||
if (m_impl->match) {
|
||||
if (!std::regex_match(std::string(value), std::regex(*m_impl->match))) {
|
||||
|
@ -1067,17 +990,6 @@ std::optional<std::vector<std::string>> StringSettingV3::getEnumOptions() const
|
|||
return m_impl->oneOf;
|
||||
}
|
||||
|
||||
bool StringSettingV3::load(matjson::Value const& json) {
|
||||
if (json.is_string()) {
|
||||
m_impl->value = json.as_string();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool StringSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* StringSettingV3::createNode(float width) {
|
||||
return StringSettingNodeV3::create(
|
||||
std::static_pointer_cast<StringSettingV3>(shared_from_this()), width
|
||||
|
@ -1100,8 +1012,6 @@ std::optional<std::shared_ptr<SettingValue>> StringSettingV3::convertToLegacyVal
|
|||
|
||||
class FileSettingV3::Impl final {
|
||||
public:
|
||||
std::filesystem::path value;
|
||||
std::filesystem::path defaultValue;
|
||||
bool folder = false;
|
||||
bool useSaveDialog = false; // this option makes no sense if folder = true
|
||||
std::optional<std::vector<utils::file::FilePickOptions::Filter>> filters;
|
||||
|
@ -1113,25 +1023,23 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
auto ret = std::make_shared<FileSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "FileSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
|
||||
// Replace known paths like `{gd-save-dir}/`
|
||||
try {
|
||||
ret->m_impl->defaultValue = fmt::format(
|
||||
fmt::runtime(ret->m_impl->defaultValue.string()),
|
||||
ret->setDefaultValue(fmt::format(
|
||||
fmt::runtime(ret->getDefaultValue().string()),
|
||||
fmt::arg("gd_dir", dirs::getGameDir()),
|
||||
fmt::arg("gd_save_dir", dirs::getSaveDir()),
|
||||
fmt::arg("mod_config_dir", dirs::getModConfigDir() / modID),
|
||||
fmt::arg("mod_save_dir", dirs::getModsSaveDir() / modID),
|
||||
fmt::arg("temp_dir", dirs::getTempDir())
|
||||
);
|
||||
));
|
||||
}
|
||||
catch(fmt::format_error const& e) {
|
||||
return Err("Invalid format string for file setting path: {}", e.what());
|
||||
}
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
ret->setValue(ret->getDefaultValue());
|
||||
|
||||
std::string type;
|
||||
root.needs("type").into(type);
|
||||
|
@ -1175,12 +1083,6 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
return root.ok(ret);
|
||||
}
|
||||
|
||||
std::filesystem::path& FileSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
std::filesystem::path FileSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> FileSettingV3::isValid(std::filesystem::path const& value) const {
|
||||
std::error_code ec;
|
||||
if (m_impl->folder) {
|
||||
|
@ -1207,17 +1109,6 @@ std::optional<std::vector<utils::file::FilePickOptions::Filter>> FileSettingV3::
|
|||
return m_impl->filters;
|
||||
}
|
||||
|
||||
bool FileSettingV3::load(matjson::Value const& json) {
|
||||
if (json.is_string()) {
|
||||
m_impl->value = json.as_string();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool FileSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* FileSettingV3::createNode(float width) {
|
||||
return FileSettingNodeV3::create(
|
||||
std::static_pointer_cast<FileSettingV3>(shared_from_this()), width
|
||||
|
@ -1238,45 +1129,22 @@ std::optional<std::shared_ptr<SettingValue>> FileSettingV3::convertToLegacyValue
|
|||
|
||||
class Color3BSettingV3::Impl final {
|
||||
public:
|
||||
ccColor3B value;
|
||||
ccColor3B defaultValue;
|
||||
};
|
||||
|
||||
Color3BSettingV3::Color3BSettingV3(PrivateMarker) : m_impl(std::make_shared<Impl>()) {}
|
||||
|
||||
Result<std::shared_ptr<Color3BSettingV3>> Color3BSettingV3::parse(std::string const& key, std::string const& modID, matjson::Value const& json) {
|
||||
auto ret = std::make_shared<Color3BSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "Color3BSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
root.checkUnknownKeys();
|
||||
return root.ok(ret);
|
||||
}
|
||||
|
||||
ccColor3B& Color3BSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
ccColor3B Color3BSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> Color3BSettingV3::isValid(ccColor3B value) const {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
bool Color3BSettingV3::load(matjson::Value const& json) {
|
||||
if (json.template is<ccColor3B>()) {
|
||||
m_impl->value = json.template as<ccColor3B>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Color3BSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* Color3BSettingV3::createNode(float width) {
|
||||
return Color3BSettingNodeV3::create(
|
||||
std::static_pointer_cast<Color3BSettingV3>(shared_from_this()), width
|
||||
|
@ -1296,45 +1164,22 @@ std::optional<std::shared_ptr<SettingValue>> Color3BSettingV3::convertToLegacyVa
|
|||
|
||||
class Color4BSettingV3::Impl final {
|
||||
public:
|
||||
ccColor4B value;
|
||||
ccColor4B defaultValue;
|
||||
};
|
||||
|
||||
Color4BSettingV3::Color4BSettingV3(PrivateMarker) : m_impl(std::make_shared<Impl>()) {}
|
||||
|
||||
Result<std::shared_ptr<Color4BSettingV3>> Color4BSettingV3::parse(std::string const& key, std::string const& modID, matjson::Value const& json) {
|
||||
auto ret = std::make_shared<Color4BSettingV3>(PrivateMarker());
|
||||
|
||||
auto root = checkJson(json, "Color4BSettingV3");
|
||||
ret->parseSharedProperties(key, modID, root);
|
||||
ret->parseDefaultValue(root, ret->m_impl->defaultValue);
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
root.checkUnknownKeys();
|
||||
return root.ok(ret);
|
||||
}
|
||||
|
||||
ccColor4B& Color4BSettingV3::getValueMut() const {
|
||||
return m_impl->value;
|
||||
}
|
||||
ccColor4B Color4BSettingV3::getDefaultValue() const {
|
||||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> Color4BSettingV3::isValid(ccColor4B value) const {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
bool Color4BSettingV3::load(matjson::Value const& json) {
|
||||
if (json.template is<ccColor4B>()) {
|
||||
m_impl->value = json.template as<ccColor4B>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Color4BSettingV3::save(matjson::Value& json) const {
|
||||
json = m_impl->value;
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* Color4BSettingV3::createNode(float width) {
|
||||
return Color4BSettingNodeV3::create(
|
||||
std::static_pointer_cast<Color4BSettingV3>(shared_from_this()), width
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <Geode/ui/ScrollLayer.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/ui/General.hpp>
|
||||
#include <loader/SettingNodeV3.hpp>
|
||||
|
||||
bool ModSettingsPopup::setup(Mod* mod) {
|
||||
m_noElasticity = true;
|
||||
|
@ -33,10 +34,9 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
node = sett->createNode(layerSize.width);
|
||||
}
|
||||
else {
|
||||
// todo: placeholder node
|
||||
continue;
|
||||
node = UnresolvedCustomSettingNodeV3::create(key, layerSize.width);
|
||||
}
|
||||
node->setBGColor(ccc4(0, 0, 0, bg ? 60 : 20));
|
||||
node->setDefaultBGColor(ccc4(0, 0, 0, bg ? 60 : 20));
|
||||
|
||||
// auto separator = CCLayerColor::create({ 0, 0, 0, 50 }, layerSize.width, 1.f);
|
||||
// separator->setOpacity(bg ? 100 : 50);
|
||||
|
@ -191,8 +191,8 @@ void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
|||
if (sett == invoker) {
|
||||
continue;
|
||||
}
|
||||
if (sett->getSetting()->getEnableIf()) {
|
||||
sett->updateState();
|
||||
if (sett->getSetting() && sett->getSetting()->getEnableIf()) {
|
||||
sett->updateState(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue