mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
make SettingValueNodeV3 keep track of the current value + some docs
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
474d85d6fe
commit
f1715cda28
5 changed files with 78 additions and 102 deletions
|
@ -173,13 +173,30 @@ namespace geode {
|
|||
*/
|
||||
std::filesystem::path getConfigDir(bool create = true) const;
|
||||
|
||||
/**
|
||||
* Returns true if this mod has any settings
|
||||
*/
|
||||
bool hasSettings() const;
|
||||
/**
|
||||
* Get a list of all this mod's setting keys (in the order they were
|
||||
* declared in `mod.json`)
|
||||
*/
|
||||
std::vector<std::string> getSettingKeys() const;
|
||||
bool hasSetting(std::string_view const key) const;
|
||||
|
||||
// todo in v4: remove these
|
||||
[[deprecated("Use Mod::getSettingV3")]]
|
||||
std::optional<Setting> getSettingDefinition(std::string_view const key) const;
|
||||
[[deprecated("Use Mod::getSettingV3")]]
|
||||
SettingValue* getSetting(std::string_view const key) const;
|
||||
|
||||
// todo in v4: possibly rename this to getSetting?
|
||||
/**
|
||||
* Get the definition of a setting, or null if the setting was not found,
|
||||
* or if it's a custom setting that has not yet been registered using
|
||||
* `Mod::registerCustomSettingType`
|
||||
* @param key The key of the setting as defined in `mod.json`
|
||||
*/
|
||||
std::shared_ptr<SettingV3> getSettingV3(std::string_view const key) const;
|
||||
|
||||
/**
|
||||
|
@ -213,7 +230,12 @@ namespace geode {
|
|||
}
|
||||
|
||||
/**
|
||||
* Register a custom setting type
|
||||
* Register a custom setting type. See
|
||||
* [the setting docs](https://docs.geode-sdk.org/mods/settings) for more
|
||||
* @param type The type of the setting. This should **not** include the
|
||||
* `custom:` prefix!
|
||||
* @param generator A pointer to a function that, when called, returns a
|
||||
* newly-created instance of the setting type
|
||||
*/
|
||||
Result<> registerCustomSettingType(std::string_view type, SettingGenerator generator);
|
||||
|
||||
|
|
|
@ -522,34 +522,46 @@ namespace geode {
|
|||
*/
|
||||
template <class S>
|
||||
class SettingValueNodeV3 : public SettingNodeV3 {
|
||||
protected:
|
||||
private:
|
||||
class Impl final {
|
||||
private:
|
||||
typename S::ValueType currentValue;
|
||||
friend class SettingValueNodeV3;
|
||||
};
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
protected:
|
||||
bool init(std::shared_ptr<S> setting, float width) {
|
||||
if (!SettingNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_impl = std::make_shared<Impl>();
|
||||
m_impl->currentValue = setting->getValue();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onCommit() override {
|
||||
this->getSetting()->setValue(this->getValue());
|
||||
this->getSetting()->setValue(m_impl->currentValue);
|
||||
}
|
||||
bool hasUncommittedChanges() const override {
|
||||
return this->getValue() != this->getSetting()->getValue();
|
||||
return m_impl->currentValue != this->getSetting()->getValue();
|
||||
}
|
||||
bool hasNonDefaultValue() const override {
|
||||
return this->getValue() != this->getSetting()->getDefaultValue();
|
||||
return m_impl->currentValue != 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;
|
||||
typename S::ValueType getValue() const {
|
||||
return m_impl->currentValue;
|
||||
}
|
||||
/**
|
||||
* Set the **uncommitted** value for this node
|
||||
* @param value The value to set
|
||||
|
@ -557,7 +569,7 @@ namespace geode {
|
|||
* for `SettingNodeV3::updateState` to know more
|
||||
*/
|
||||
void setValue(typename S::ValueAssignType value, cocos2d::CCNode* invoker) {
|
||||
this->onSetValue(value);
|
||||
m_impl->currentValue = value;
|
||||
this->markChanged(invoker);
|
||||
}
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ bool BoolSettingNodeV3::init(std::shared_ptr<BoolSettingV3> setting, float width
|
|||
void BoolSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
m_toggle->toggle(this->getValue());
|
||||
m_toggle->setCascadeColorEnabled(true);
|
||||
m_toggle->setCascadeOpacityEnabled(true);
|
||||
m_toggle->setEnabled(enable);
|
||||
|
@ -286,17 +287,10 @@ void BoolSettingNodeV3::updateState(CCNode* invoker) {
|
|||
}
|
||||
|
||||
void BoolSettingNodeV3::onToggle(CCObject*) {
|
||||
m_toggle->toggle(!m_toggle->isToggled());
|
||||
this->setValue(!m_toggle->isToggled(), m_toggle);
|
||||
this->markChanged(m_toggle);
|
||||
}
|
||||
|
||||
bool BoolSettingNodeV3::getValue() const {
|
||||
return m_toggle->isToggled();
|
||||
}
|
||||
void BoolSettingNodeV3::onSetValue(bool value) {
|
||||
m_toggle->toggle(value);
|
||||
}
|
||||
|
||||
BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr<BoolSettingV3> setting, float width) {
|
||||
auto ret = new BoolSettingNodeV3();
|
||||
if (ret && ret->init(setting, width)) {
|
||||
|
@ -352,6 +346,11 @@ bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float w
|
|||
|
||||
void StringSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
|
||||
if (invoker != m_input) {
|
||||
m_input->setString(this->getValue());
|
||||
}
|
||||
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
if (!this->getSetting()->getEnumOptions()) {
|
||||
m_input->setEnabled(enable);
|
||||
|
@ -366,22 +365,14 @@ void StringSettingNodeV3::updateState(CCNode* invoker) {
|
|||
|
||||
void StringSettingNodeV3::onArrow(CCObject* sender) {
|
||||
auto options = *this->getSetting()->getEnumOptions();
|
||||
auto index = ranges::indexOf(options, m_input->getString()).value_or(0);
|
||||
auto index = ranges::indexOf(options, this->getValue()).value_or(0);
|
||||
if (sender->getTag() > 0) {
|
||||
index = index < options.size() - 1 ? index + 1 : 0;
|
||||
}
|
||||
else {
|
||||
index = index > 0 ? index - 1 : options.size() - 1;
|
||||
}
|
||||
m_input->setString(options.at(index));
|
||||
this->updateState(static_cast<CCNode*>(sender));
|
||||
}
|
||||
|
||||
std::string StringSettingNodeV3::getValue() const {
|
||||
return m_input->getString();
|
||||
}
|
||||
void StringSettingNodeV3::onSetValue(std::string_view value) {
|
||||
m_input->setString(std::string(value));
|
||||
this->setValue(options.at(index), static_cast<CCNode*>(sender));
|
||||
}
|
||||
|
||||
StringSettingNodeV3* StringSettingNodeV3::create(std::shared_ptr<StringSettingV3> setting, float width) {
|
||||
|
@ -400,8 +391,6 @@ bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width
|
|||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_path = setting->getValue();
|
||||
|
||||
auto labelBG = extension::CCScale9Sprite::create("square02b_001.png", { 0, 0, 80, 80 });
|
||||
labelBG->setScale(.25f);
|
||||
labelBG->setColor({ 0, 0, 0 });
|
||||
|
@ -433,13 +422,13 @@ void FileSettingNodeV3::updateState(CCNode* invoker) {
|
|||
this->getSetting()->isFolder() ? "folderIcon_001.png" : "file.png"_spr
|
||||
));
|
||||
limitNodeSize(m_fileIcon, ccp(10, 10), 1.f, .1f);
|
||||
if (m_path.empty()) {
|
||||
if (this->getValue().empty()) {
|
||||
m_nameLabel->setString(this->getSetting()->isFolder() ? "No Folder Selected" : "No File Selected");
|
||||
m_nameLabel->setColor(ccGRAY);
|
||||
m_nameLabel->setOpacity(155);
|
||||
}
|
||||
else {
|
||||
m_nameLabel->setString(m_path.filename().string().c_str());
|
||||
m_nameLabel->setString(this->getValue().filename().string().c_str());
|
||||
m_nameLabel->setColor(ccWHITE);
|
||||
m_nameLabel->setOpacity(255);
|
||||
}
|
||||
|
@ -458,8 +447,7 @@ void FileSettingNodeV3::onPickFile(CCObject*) {
|
|||
return;
|
||||
}
|
||||
if (value->isOk()) {
|
||||
m_path = value->unwrap().string();
|
||||
this->markChanged(nullptr);
|
||||
this->setValue(value->unwrap(), nullptr);
|
||||
}
|
||||
else {
|
||||
FLAlertLayer::create(
|
||||
|
@ -476,19 +464,14 @@ void FileSettingNodeV3::onPickFile(CCObject*) {
|
|||
(this->getSetting()->useSaveDialog() ? file::PickMode::SaveFile : file::PickMode::OpenFile),
|
||||
{
|
||||
// Prefer opening the current path directly if possible
|
||||
m_path.empty() || !std::filesystem::exists(m_path.parent_path(), ec) ? dirs::getGameDir() : m_path,
|
||||
this->getValue().empty() || !std::filesystem::exists(this->getValue().parent_path(), ec) ?
|
||||
dirs::getGameDir() :
|
||||
this->getValue(),
|
||||
this->getSetting()->getFilters().value_or(std::vector<file::FilePickOptions::Filter>())
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
std::filesystem::path FileSettingNodeV3::getValue() const {
|
||||
return m_path;
|
||||
}
|
||||
void FileSettingNodeV3::onSetValue(std::filesystem::path const& value) {
|
||||
m_path = value;
|
||||
}
|
||||
|
||||
FileSettingNodeV3* FileSettingNodeV3::create(std::shared_ptr<FileSettingV3> setting, float width) {
|
||||
auto ret = new FileSettingNodeV3();
|
||||
if (ret && ret->init(setting, width)) {
|
||||
|
@ -505,8 +488,6 @@ bool Color3BSettingNodeV3::init(std::shared_ptr<Color3BSettingV3> setting, float
|
|||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_value = setting->getValue();
|
||||
|
||||
m_colorSprite = ColorChannelSprite::create();
|
||||
m_colorSprite->setScale(.65f);
|
||||
|
||||
|
@ -522,7 +503,7 @@ bool Color3BSettingNodeV3::init(std::shared_ptr<Color3BSettingV3> setting, float
|
|||
|
||||
void Color3BSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
m_colorSprite->setColor(m_value);
|
||||
m_colorSprite->setColor(this->getValue());
|
||||
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
m_colorSprite->setOpacity(enable ? 255 : 155);
|
||||
|
@ -530,20 +511,12 @@ void Color3BSettingNodeV3::updateState(CCNode* invoker) {
|
|||
}
|
||||
|
||||
void Color3BSettingNodeV3::onSelectColor(CCObject*) {
|
||||
auto popup = ColorPickPopup::create(m_value);
|
||||
auto popup = ColorPickPopup::create(this->getValue());
|
||||
popup->setDelegate(this);
|
||||
popup->show();
|
||||
}
|
||||
void Color3BSettingNodeV3::updateColor(ccColor4B const& color) {
|
||||
m_value = to3B(color);
|
||||
this->markChanged(nullptr);
|
||||
}
|
||||
|
||||
ccColor3B Color3BSettingNodeV3::getValue() const {
|
||||
return m_value;
|
||||
}
|
||||
void Color3BSettingNodeV3::onSetValue(ccColor3B value) {
|
||||
m_value = value;
|
||||
this->setValue(to3B(color), nullptr);
|
||||
}
|
||||
|
||||
Color3BSettingNodeV3* Color3BSettingNodeV3::create(std::shared_ptr<Color3BSettingV3> setting, float width) {
|
||||
|
@ -562,8 +535,6 @@ bool Color4BSettingNodeV3::init(std::shared_ptr<Color4BSettingV3> setting, float
|
|||
if (!SettingValueNodeV3::init(setting, width))
|
||||
return false;
|
||||
|
||||
m_value = setting->getValue();
|
||||
|
||||
m_colorSprite = ColorChannelSprite::create();
|
||||
m_colorSprite->setScale(.65f);
|
||||
|
||||
|
@ -579,8 +550,8 @@ bool Color4BSettingNodeV3::init(std::shared_ptr<Color4BSettingV3> setting, float
|
|||
|
||||
void Color4BSettingNodeV3::updateState(CCNode* invoker) {
|
||||
SettingNodeV3::updateState(invoker);
|
||||
m_colorSprite->setColor(to3B(m_value));
|
||||
m_colorSprite->updateOpacity(m_value.a / 255.f);
|
||||
m_colorSprite->setColor(to3B(this->getValue()));
|
||||
m_colorSprite->updateOpacity(this->getValue().a / 255.f);
|
||||
|
||||
auto enable = this->getSetting()->shouldEnable();
|
||||
m_colorSprite->setOpacity(enable ? 255 : 155);
|
||||
|
@ -588,20 +559,12 @@ void Color4BSettingNodeV3::updateState(CCNode* invoker) {
|
|||
}
|
||||
|
||||
void Color4BSettingNodeV3::onSelectColor(CCObject*) {
|
||||
auto popup = ColorPickPopup::create(m_value);
|
||||
auto popup = ColorPickPopup::create(this->getValue());
|
||||
popup->setDelegate(this);
|
||||
popup->show();
|
||||
}
|
||||
void Color4BSettingNodeV3::updateColor(ccColor4B const& color) {
|
||||
m_value = color;
|
||||
this->markChanged(nullptr);
|
||||
}
|
||||
|
||||
ccColor4B Color4BSettingNodeV3::getValue() const {
|
||||
return m_value;
|
||||
}
|
||||
void Color4BSettingNodeV3::onSetValue(ccColor4B value) {
|
||||
m_value = value;
|
||||
this->setValue(color, nullptr);
|
||||
}
|
||||
|
||||
Color4BSettingNodeV3* Color4BSettingNodeV3::create(std::shared_ptr<Color4BSettingV3> setting, float width) {
|
||||
|
|
|
@ -36,9 +36,6 @@ protected:
|
|||
void onToggle(CCObject*);
|
||||
|
||||
public:
|
||||
bool getValue() const override;
|
||||
void onSetValue(bool value) override;
|
||||
|
||||
static BoolSettingNodeV3* create(std::shared_ptr<BoolSettingV3> setting, float width);
|
||||
};
|
||||
|
||||
|
@ -172,6 +169,10 @@ protected:
|
|||
m_input->setEnabled(enable);
|
||||
}
|
||||
|
||||
if (invoker != m_input) {
|
||||
m_input->setString(numToString(this->getValue()));
|
||||
}
|
||||
|
||||
auto min = this->getSetting()->getMinValue();
|
||||
auto enableLeft = enable && (!min || this->getValue() > *min);
|
||||
m_arrowLeftBtn->setEnabled(enableLeft);
|
||||
|
@ -215,14 +216,6 @@ protected:
|
|||
this->setValue(this->valueFromSlider(m_slider->m_touchLogic->m_thumb->getValue()), m_slider);
|
||||
}
|
||||
|
||||
ValueType getValue() const override {
|
||||
return numFromString<ValueType>(m_input->getString())
|
||||
.value_or(this->getSetting()->getDefaultValue());
|
||||
}
|
||||
void onSetValue(ValueAssignType value) override {
|
||||
m_input->setString(numToString(value));
|
||||
}
|
||||
|
||||
public:
|
||||
static NumberSettingNodeV3* create(std::shared_ptr<S> setting, float width) {
|
||||
auto ret = new NumberSettingNodeV3();
|
||||
|
@ -250,15 +243,11 @@ protected:
|
|||
|
||||
public:
|
||||
static StringSettingNodeV3* create(std::shared_ptr<StringSettingV3> setting, float width);
|
||||
|
||||
std::string getValue() const override;
|
||||
void onSetValue(std::string_view value) override;
|
||||
};
|
||||
|
||||
class FileSettingNodeV3 : public SettingValueNodeV3<FileSettingV3> {
|
||||
protected:
|
||||
CCSprite* m_fileIcon;
|
||||
std::filesystem::path m_path;
|
||||
CCLabelBMFont* m_nameLabel;
|
||||
EventListener<Task<Result<std::filesystem::path>>> m_pickListener;
|
||||
CCMenuItemSpriteExtra* m_selectBtn;
|
||||
|
@ -270,14 +259,10 @@ protected:
|
|||
|
||||
public:
|
||||
static FileSettingNodeV3* create(std::shared_ptr<FileSettingV3> setting, float width);
|
||||
|
||||
std::filesystem::path getValue() const override;
|
||||
void onSetValue(std::filesystem::path const& value) override;
|
||||
};
|
||||
|
||||
class Color3BSettingNodeV3 : public SettingValueNodeV3<Color3BSettingV3>, public ColorPickPopupDelegate {
|
||||
protected:
|
||||
ccColor3B m_value;
|
||||
CCMenuItemSpriteExtra* m_colorBtn;
|
||||
ColorChannelSprite* m_colorSprite;
|
||||
|
||||
|
@ -288,14 +273,10 @@ protected:
|
|||
|
||||
public:
|
||||
static Color3BSettingNodeV3* create(std::shared_ptr<Color3BSettingV3> setting, float width);
|
||||
|
||||
ccColor3B getValue() const override;
|
||||
void onSetValue(ccColor3B value) override;
|
||||
};
|
||||
|
||||
class Color4BSettingNodeV3 : public SettingValueNodeV3<Color4BSettingV3>, public ColorPickPopupDelegate {
|
||||
protected:
|
||||
ccColor4B m_value;
|
||||
CCMenuItemSpriteExtra* m_colorBtn;
|
||||
ColorChannelSprite* m_colorSprite;
|
||||
|
||||
|
@ -306,9 +287,6 @@ protected:
|
|||
|
||||
public:
|
||||
static Color4BSettingNodeV3* create(std::shared_ptr<Color4BSettingV3> setting, float width);
|
||||
|
||||
ccColor4B getValue() const override;
|
||||
void onSetValue(ccColor4B value) override;
|
||||
};
|
||||
|
||||
class UnresolvedCustomSettingNodeV3 : public SettingNodeV3 {
|
||||
|
|
|
@ -1055,17 +1055,18 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
key, modID
|
||||
);
|
||||
}
|
||||
std::string dialogType;
|
||||
root.has("dialog").into(dialogType);
|
||||
switch (hash(dialogType)) {
|
||||
case hash("save"): ret->m_impl->useSaveDialog = true; break;
|
||||
case hash("open"): ret->m_impl->useSaveDialog = false; break;
|
||||
case hash(""): break;
|
||||
default: return Err("Setting '{}' in mod {}: unknown \"dialog\" type \"{}\"", key, modID, dialogType);
|
||||
}
|
||||
|
||||
// Filter controls only make sense for files but not for folders
|
||||
// Controls only make sense for files but not for folders
|
||||
if (auto controls = root.has("control")) {
|
||||
std::string dialogType;
|
||||
controls.has("dialog").into(dialogType);
|
||||
switch (hash(dialogType)) {
|
||||
case hash("save"): ret->m_impl->useSaveDialog = true; break;
|
||||
case hash("open"): ret->m_impl->useSaveDialog = false; break;
|
||||
case hash(""): break;
|
||||
default: return Err("Setting '{}' in mod {}: unknown \"dialog\" type \"{}\"", key, modID, dialogType);
|
||||
}
|
||||
|
||||
auto filters = std::vector<file::FilePickOptions::Filter>();
|
||||
for (auto& item : controls.has("filters").items()) {
|
||||
utils::file::FilePickOptions::Filter filter;
|
||||
|
|
Loading…
Reference in a new issue