From 6ed6b326697cc47447b12cecf2901269f8f35635 Mon Sep 17 00:00:00 2001 From: HJfod <60038575+HJfod@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:22:57 +0300 Subject: [PATCH] int and float setting nodes --- loader/include/Geode/loader/SettingV3.hpp | 7 +- loader/src/loader/SettingNodeV3.cpp | 505 +++++++++++++----- loader/src/loader/SettingNodeV3.hpp | 41 +- loader/src/loader/SettingV3.cpp | 35 +- .../src/ui/mods/settings/ModSettingsPopup.cpp | 2 + 5 files changed, 442 insertions(+), 148 deletions(-) diff --git a/loader/include/Geode/loader/SettingV3.hpp b/loader/include/Geode/loader/SettingV3.hpp index dd784837..03506ca5 100644 --- a/loader/include/Geode/loader/SettingV3.hpp +++ b/loader/include/Geode/loader/SettingV3.hpp @@ -47,6 +47,10 @@ namespace geode { * Get the name of this setting */ std::optional getName() const; + /** + * Get the name of this setting, or its key if it has no name + */ + std::string getDisplayName() const; /** * Get the description of this setting */ @@ -413,15 +417,16 @@ namespace geode { * the value in some sort of global manager */ virtual void onCommit() = 0; + virtual void onResetToDefault() = 0; void onDescription(CCObject*); void onReset(CCObject*); public: void commit(); + void resetToDefault(); virtual bool hasUncommittedChanges() const = 0; virtual bool hasNonDefaultValue() const = 0; - virtual void resetToDefault() = 0; cocos2d::CCLabelBMFont* getNameLabel() const; cocos2d::CCMenu* getNameMenu() const; diff --git a/loader/src/loader/SettingNodeV3.cpp b/loader/src/loader/SettingNodeV3.cpp index 21260852..a8a25cb8 100644 --- a/loader/src/loader/SettingNodeV3.cpp +++ b/loader/src/loader/SettingNodeV3.cpp @@ -1,6 +1,27 @@ #include "SettingNodeV3.hpp" #include +template +static float valueToSlider(std::shared_ptr setting, typename T::ValueType value) { + auto min = setting->getMinValue().value_or(-100); + auto max = setting->getMaxValue().value_or(+100); + auto range = max - min; + return static_cast(clamp(static_cast(value - min) / range, 0.0, 1.0)); +} +template +static typename T::ValueType valueFromSlider(std::shared_ptr setting, float num) { + auto min = setting->getMinValue().value_or(-100); + auto max = setting->getMaxValue().value_or(+100); + auto range = max - min; + auto value = static_cast(num * range + min); + if (auto step = setting->getSliderSnap()) { + value = static_cast( + round(value / *step) * (*step) + ); + } + return value; +} + class SettingNodeSizeChangeEventV3::Impl final { public: SettingNodeV3* node; @@ -52,10 +73,7 @@ bool SettingNodeV3::init(std::shared_ptr setting, float width) { m_impl->nameMenu = CCMenu::create(); m_impl->nameMenu->setContentWidth(width / 2 - 20); - m_impl->nameLabel = CCLabelBMFont::create( - setting->getName().value_or(setting->getKey()).c_str(), - "bigFont.fnt" - ); + m_impl->nameLabel = CCLabelBMFont::create(setting->getDisplayName().c_str(), "bigFont.fnt"); m_impl->nameLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .4f)->setScalePriority(1)); m_impl->nameMenu->addChild(m_impl->nameLabel); @@ -96,7 +114,7 @@ void SettingNodeV3::updateState() { } void SettingNodeV3::onDescription(CCObject*) { - auto title = m_impl->setting->getName().value_or(m_impl->setting->getKey()); + auto title = m_impl->setting->getDisplayName(); FLAlertLayer::create( nullptr, title.c_str(), @@ -106,8 +124,19 @@ void SettingNodeV3::onDescription(CCObject*) { )->show(); } void SettingNodeV3::onReset(CCObject*) { - this->resetToDefault(); - this->updateState(); + createQuickPopup( + "Reset", + fmt::format( + "Are you sure you want to reset {} to default?", + this->getSetting()->getDisplayName() + ), + "Cancel", "Reset", + [this](auto, bool btn2) { + if (btn2) { + this->resetToDefault(); + } + } + ); } void SettingNodeV3::markChanged() { @@ -119,6 +148,12 @@ void SettingNodeV3::commit() { this->updateState(); SettingNodeValueChangeEventV3(true).post(); } +void SettingNodeV3::resetToDefault() { + m_impl->setting->reset(); + this->onResetToDefault(); + this->updateState(); + SettingNodeValueChangeEventV3(false).post(); +} void SettingNodeV3::setContentSize(CCSize const& size) { CCNode::setContentSize(size); @@ -156,6 +191,18 @@ bool TitleSettingNodeV3::init(std::shared_ptr setting, float wid void TitleSettingNodeV3::onCommit() {} +bool TitleSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool TitleSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void TitleSettingNodeV3::onResetToDefault() {} + +std::shared_ptr TitleSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + TitleSettingNodeV3* TitleSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new TitleSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -166,18 +213,6 @@ TitleSettingNodeV3* TitleSettingNodeV3::create(std::shared_ptr s return nullptr; } -bool TitleSettingNodeV3::hasUncommittedChanges() const { - return false; -} -bool TitleSettingNodeV3::hasNonDefaultValue() const { - return false; -} -void TitleSettingNodeV3::resetToDefault() {} - -std::shared_ptr TitleSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // BoolSettingNodeV3 bool BoolSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -209,6 +244,20 @@ void BoolSettingNodeV3::onToggle(CCObject*) { this->markChanged(); } +bool BoolSettingNodeV3::hasUncommittedChanges() const { + return m_toggle->isToggled() != this->getSetting()->getValue(); +} +bool BoolSettingNodeV3::hasNonDefaultValue() const { + return m_toggle->isToggled() != this->getSetting()->getDefaultValue(); +} +void BoolSettingNodeV3::onResetToDefault() { + m_toggle->toggle(this->getSetting()->getDefaultValue()); +} + +std::shared_ptr BoolSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new BoolSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -219,33 +268,134 @@ BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr sett return nullptr; } -bool BoolSettingNodeV3::hasUncommittedChanges() const { - return m_toggle->isToggled() != this->getSetting()->getValue(); -} -bool BoolSettingNodeV3::hasNonDefaultValue() const { - return m_toggle->isToggled() != this->getSetting()->getDefaultValue(); -} -void BoolSettingNodeV3::resetToDefault() { - this->getSetting()->reset(); - m_toggle->toggle(this->getSetting()->getDefaultValue()); -} - -std::shared_ptr BoolSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // IntSettingNodeV3 bool IntSettingNodeV3::init(std::shared_ptr setting, float width) { if (!SettingNodeV3::init(setting, width)) return false; + + auto bigArrowLeftSpr = CCSprite::create(); + auto bigArrowLeftSpr1 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + auto bigArrowLeftSpr2 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); - // todo + bigArrowLeftSpr->setContentSize(bigArrowLeftSpr1->getContentSize() + ccp(20, 0)); + bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr2, Anchor::Center, ccp(10, 0)); + bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr1, Anchor::Center, ccp(-10, 0)); + bigArrowLeftSpr->setScale(.45f); + + auto bigArrowLeftBtn = CCMenuItemSpriteExtra::create( + bigArrowLeftSpr, this, menu_selector(IntSettingNodeV3::onArrow) + ); + bigArrowLeftBtn->setTag(-setting->getBigArrowStepSize()); + bigArrowLeftBtn->setVisible(setting->isBigArrowsEnabled()); + this->getButtonMenu()->addChild(bigArrowLeftBtn); + + auto arrowLeftSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); + arrowLeftSpr->setScale(.65f); + auto arrowLeftBtn = CCMenuItemSpriteExtra::create( + arrowLeftSpr, this, menu_selector(IntSettingNodeV3::onArrow) + ); + arrowLeftBtn->setTag(-setting->getArrowStepSize()); + arrowLeftBtn->setVisible(setting->isArrowsEnabled()); + this->getButtonMenu()->addChild(arrowLeftBtn); + + m_input = TextInput::create(width / 2 - 70, "Num"); + m_input->setCallback([this](auto const&) { + this->markChanged(); + }); + if (!setting->isInputEnabled()) { + m_input->getBGSprite()->setVisible(false); + m_input->setEnabled(false); + } + this->getButtonMenu()->addChild(m_input); + + auto arrowRightSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); + arrowRightSpr->setFlipX(true); + arrowRightSpr->setScale(.65f); + auto arrowRightBtn = CCMenuItemSpriteExtra::create( + arrowRightSpr, this, menu_selector(IntSettingNodeV3::onArrow) + ); + arrowRightBtn->setTag(setting->getArrowStepSize()); + arrowRightBtn->setVisible(setting->isArrowsEnabled()); + this->getButtonMenu()->addChild(arrowRightBtn); + + auto bigArrowRightSpr = CCSprite::create(); + auto bigArrowRightSpr1 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + bigArrowRightSpr1->setFlipX(true); + auto bigArrowRightSpr2 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + bigArrowRightSpr2->setFlipX(true); + + bigArrowRightSpr->setContentSize(bigArrowRightSpr1->getContentSize() + ccp(20, 0)); + bigArrowRightSpr->addChildAtPosition(bigArrowRightSpr1, Anchor::Center, ccp(-10, 0)); + bigArrowRightSpr->addChildAtPosition(bigArrowRightSpr2, Anchor::Center, ccp(10, 0)); + bigArrowRightSpr->setScale(.45f); + + auto bigArrowRightBtn = CCMenuItemSpriteExtra::create( + bigArrowRightSpr, this, menu_selector(IntSettingNodeV3::onArrow) + ); + bigArrowRightBtn->setTag(setting->getBigArrowStepSize()); + bigArrowRightBtn->setVisible(setting->isBigArrowsEnabled()); + this->getButtonMenu()->addChild(bigArrowRightBtn); + + if (setting->isSliderEnabled()) { + this->setContentHeight(45); + this->getButtonMenu()->updateAnchoredPosition(Anchor::Right, ccp(0, 7)); + + m_slider = Slider::create(this, menu_selector(IntSettingNodeV3::onSlider)); + m_slider->setScale(.5f); + this->addChildAtPosition(m_slider, Anchor::Right, ccp(-75, -12), ccp(0, 0)); + } + + this->setCurrentValue(setting->getValue()); + this->getButtonMenu()->updateLayout(); + this->updateState(); return true; } -void IntSettingNodeV3::onCommit() {} +void IntSettingNodeV3::updateState() { + SettingNodeV3::updateState(); + m_slider->m_touchLogic->m_thumb->setValue(valueToSlider( + this->getSetting(), this->getCurrentValue() + )); + m_slider->updateBar(); +} + +int64_t IntSettingNodeV3::getCurrentValue() const { + return numFromString(m_input->getString()).value_or(this->getSetting()->getDefaultValue()); +} +void IntSettingNodeV3::setCurrentValue(int64_t value) { + m_input->setString(std::to_string(value)); + this->markChanged(); +} + +void IntSettingNodeV3::onCommit() { + this->getSetting()->setValue(this->getCurrentValue()); +} +void IntSettingNodeV3::onArrow(CCObject* sender) { + this->setCurrentValue(this->getCurrentValue() + sender->getTag()); + this->updateState(); +} +void IntSettingNodeV3::onSlider(CCObject* sender) { + this->setCurrentValue(valueFromSlider( + this->getSetting(), + m_slider->m_touchLogic->m_thumb->getValue() + )); +} + +bool IntSettingNodeV3::hasUncommittedChanges() const { + return this->getSetting()->getValue() != this->getCurrentValue(); +} +bool IntSettingNodeV3::hasNonDefaultValue() const { + return this->getSetting()->getDefaultValue() != this->getCurrentValue(); +} +void IntSettingNodeV3::onResetToDefault() { + this->setCurrentValue(this->getSetting()->getDefaultValue()); +} + +std::shared_ptr IntSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} IntSettingNodeV3* IntSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new IntSettingNodeV3(); @@ -257,30 +407,133 @@ IntSettingNodeV3* IntSettingNodeV3::create(std::shared_ptr setting return nullptr; } -bool IntSettingNodeV3::hasUncommittedChanges() const { - return false; -} -bool IntSettingNodeV3::hasNonDefaultValue() const { - return false; -} -void IntSettingNodeV3::resetToDefault() {} - -std::shared_ptr IntSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // FloatSettingNodeV3 bool FloatSettingNodeV3::init(std::shared_ptr setting, float width) { if (!SettingNodeV3::init(setting, width)) return false; - // todo + auto bigArrowLeftSpr = CCSprite::create(); + auto bigArrowLeftSpr1 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + auto bigArrowLeftSpr2 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + + bigArrowLeftSpr->setContentSize(bigArrowLeftSpr1->getContentSize() + ccp(20, 0)); + bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr2, Anchor::Center, ccp(10, 0)); + bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr1, Anchor::Center, ccp(-10, 0)); + bigArrowLeftSpr->setScale(.45f); + + auto bigArrowLeftBtn = CCMenuItemSpriteExtra::create( + bigArrowLeftSpr, this, menu_selector(FloatSettingNodeV3::onArrow) + ); + bigArrowLeftBtn->setTag(-setting->getBigArrowStepSize()); + bigArrowLeftBtn->setVisible(setting->isBigArrowsEnabled()); + this->getButtonMenu()->addChild(bigArrowLeftBtn); + + auto arrowLeftSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); + arrowLeftSpr->setScale(.65f); + auto arrowLeftBtn = CCMenuItemSpriteExtra::create( + arrowLeftSpr, this, menu_selector(FloatSettingNodeV3::onArrow) + ); + arrowLeftBtn->setTag(-setting->getArrowStepSize()); + arrowLeftBtn->setVisible(setting->isArrowsEnabled()); + this->getButtonMenu()->addChild(arrowLeftBtn); + + m_input = TextInput::create(width / 2 - 70, "Num"); + m_input->setCallback([this](auto const&) { + this->markChanged(); + }); + if (!setting->isInputEnabled()) { + m_input->getBGSprite()->setVisible(false); + m_input->setEnabled(false); + } + this->getButtonMenu()->addChild(m_input); + + auto arrowRightSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png"); + arrowRightSpr->setFlipX(true); + arrowRightSpr->setScale(.65f); + auto arrowRightBtn = CCMenuItemSpriteExtra::create( + arrowRightSpr, this, menu_selector(FloatSettingNodeV3::onArrow) + ); + arrowRightBtn->setTag(setting->getArrowStepSize()); + arrowRightBtn->setVisible(setting->isArrowsEnabled()); + this->getButtonMenu()->addChild(arrowRightBtn); + + auto bigArrowRightSpr = CCSprite::create(); + auto bigArrowRightSpr1 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + bigArrowRightSpr1->setFlipX(true); + auto bigArrowRightSpr2 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png"); + bigArrowRightSpr2->setFlipX(true); + + bigArrowRightSpr->setContentSize(bigArrowRightSpr1->getContentSize() + ccp(20, 0)); + bigArrowRightSpr->addChildAtPosition(bigArrowRightSpr1, Anchor::Center, ccp(-10, 0)); + bigArrowRightSpr->addChildAtPosition(bigArrowRightSpr2, Anchor::Center, ccp(10, 0)); + bigArrowRightSpr->setScale(.45f); + + auto bigArrowRightBtn = CCMenuItemSpriteExtra::create( + bigArrowRightSpr, this, menu_selector(FloatSettingNodeV3::onArrow) + ); + bigArrowRightBtn->setTag(setting->getBigArrowStepSize()); + bigArrowRightBtn->setVisible(setting->isBigArrowsEnabled()); + this->getButtonMenu()->addChild(bigArrowRightBtn); + + if (setting->isSliderEnabled()) { + this->setContentHeight(45); + this->getButtonMenu()->updateAnchoredPosition(Anchor::Right, ccp(0, 7)); + + m_slider = Slider::create(this, menu_selector(FloatSettingNodeV3::onSlider)); + m_slider->setScale(.5f); + this->addChildAtPosition(m_slider, Anchor::Right, ccp(-75, -12), ccp(0, 0)); + } + + this->setCurrentValue(setting->getValue()); + this->getButtonMenu()->updateLayout(); + this->updateState(); return true; } -void FloatSettingNodeV3::onCommit() {} +void FloatSettingNodeV3::updateState() { + SettingNodeV3::updateState(); + m_slider->m_touchLogic->m_thumb->setValue(valueToSlider( + this->getSetting(), this->getCurrentValue() + )); + m_slider->updateBar(); +} + +double FloatSettingNodeV3::getCurrentValue() const { + return numFromString(m_input->getString()).value_or(this->getSetting()->getDefaultValue()); +} +void FloatSettingNodeV3::setCurrentValue(double value) { + m_input->setString(numToString(value)); +} + +void FloatSettingNodeV3::onCommit() { + this->getSetting()->setValue(this->getCurrentValue()); +} +void FloatSettingNodeV3::onArrow(CCObject* sender) { + this->setCurrentValue(this->getCurrentValue() + sender->getTag()); + this->updateState(); +} +void FloatSettingNodeV3::onSlider(CCObject* sender) { + this->setCurrentValue(valueFromSlider( + this->getSetting(), + m_slider->m_touchLogic->m_thumb->getValue() + )); +} + +bool FloatSettingNodeV3::hasUncommittedChanges() const { + return this->getSetting()->getValue() != this->getCurrentValue(); +} +bool FloatSettingNodeV3::hasNonDefaultValue() const { + return this->getSetting()->getDefaultValue() != this->getCurrentValue(); +} +void FloatSettingNodeV3::onResetToDefault() { + this->setCurrentValue(this->getSetting()->getDefaultValue()); +} + +std::shared_ptr FloatSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} FloatSettingNodeV3* FloatSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new FloatSettingNodeV3(); @@ -292,18 +545,6 @@ FloatSettingNodeV3* FloatSettingNodeV3::create(std::shared_ptr s return nullptr; } -bool FloatSettingNodeV3::hasUncommittedChanges() const { - return false; -} -bool FloatSettingNodeV3::hasNonDefaultValue() const { - return false; -} -void FloatSettingNodeV3::resetToDefault() {} - -std::shared_ptr FloatSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // StringSettingNodeV3 bool StringSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -317,6 +558,18 @@ bool StringSettingNodeV3::init(std::shared_ptr setting, float w void StringSettingNodeV3::onCommit() {} +bool StringSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool StringSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void StringSettingNodeV3::onResetToDefault() {} + +std::shared_ptr StringSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + StringSettingNodeV3* StringSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new StringSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -327,18 +580,6 @@ StringSettingNodeV3* StringSettingNodeV3::create(std::shared_ptr StringSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // FileSettingNodeV3 bool FileSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -352,6 +593,18 @@ bool FileSettingNodeV3::init(std::shared_ptr setting, float width void FileSettingNodeV3::onCommit() {} +bool FileSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool FileSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void FileSettingNodeV3::onResetToDefault() {} + +std::shared_ptr FileSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + FileSettingNodeV3* FileSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new FileSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -362,18 +615,6 @@ FileSettingNodeV3* FileSettingNodeV3::create(std::shared_ptr sett return nullptr; } -bool FileSettingNodeV3::hasUncommittedChanges() const { - return false; -} -bool FileSettingNodeV3::hasNonDefaultValue() const { - return false; -} -void FileSettingNodeV3::resetToDefault() {} - -std::shared_ptr FileSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // Color3BSettingNodeV3 bool Color3BSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -387,6 +628,18 @@ bool Color3BSettingNodeV3::init(std::shared_ptr setting, float void Color3BSettingNodeV3::onCommit() {} +bool Color3BSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool Color3BSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void Color3BSettingNodeV3::onResetToDefault() {} + +std::shared_ptr Color3BSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + Color3BSettingNodeV3* Color3BSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new Color3BSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -397,18 +650,6 @@ Color3BSettingNodeV3* Color3BSettingNodeV3::create(std::shared_ptr Color3BSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // Color4BSettingNodeV3 bool Color4BSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -422,6 +663,18 @@ bool Color4BSettingNodeV3::init(std::shared_ptr setting, float void Color4BSettingNodeV3::onCommit() {} +bool Color4BSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool Color4BSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void Color4BSettingNodeV3::onResetToDefault() {} + +std::shared_ptr Color4BSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + Color4BSettingNodeV3* Color4BSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new Color4BSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -432,18 +685,6 @@ Color4BSettingNodeV3* Color4BSettingNodeV3::create(std::shared_ptr Color4BSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // UnresolvedCustomSettingNodeV3 bool UnresolvedCustomSettingNodeV3::init(std::shared_ptr setting, float width) { @@ -464,6 +705,18 @@ bool UnresolvedCustomSettingNodeV3::init(std::shared_ptr void UnresolvedCustomSettingNodeV3::onCommit() {} +bool UnresolvedCustomSettingNodeV3::hasUncommittedChanges() const { + return false; +} +bool UnresolvedCustomSettingNodeV3::hasNonDefaultValue() const { + return false; +} +void UnresolvedCustomSettingNodeV3::onResetToDefault() {} + +std::shared_ptr UnresolvedCustomSettingNodeV3::getSetting() const { + return std::static_pointer_cast(SettingNodeV3::getSetting()); +} + UnresolvedCustomSettingNodeV3* UnresolvedCustomSettingNodeV3::create(std::shared_ptr setting, float width) { auto ret = new UnresolvedCustomSettingNodeV3(); if (ret && ret->init(setting, width)) { @@ -474,18 +727,6 @@ UnresolvedCustomSettingNodeV3* UnresolvedCustomSettingNodeV3::create(std::shared return nullptr; } -bool UnresolvedCustomSettingNodeV3::hasUncommittedChanges() const { - return false; -} -bool UnresolvedCustomSettingNodeV3::hasNonDefaultValue() const { - return false; -} -void UnresolvedCustomSettingNodeV3::resetToDefault() {} - -std::shared_ptr UnresolvedCustomSettingNodeV3::getSetting() const { - return std::static_pointer_cast(SettingNodeV3::getSetting()); -} - // LegacyCustomSettingToV3Node bool LegacyCustomSettingToV3Node::init(std::shared_ptr original, float width) { @@ -503,6 +744,16 @@ void LegacyCustomSettingToV3Node::onCommit() { m_original->commit(); } +bool LegacyCustomSettingToV3Node::hasUncommittedChanges() const { + return m_original->hasUncommittedChanges(); +} +bool LegacyCustomSettingToV3Node::hasNonDefaultValue() const { + return m_original->hasNonDefaultValue(); +} +void LegacyCustomSettingToV3Node::onResetToDefault() { + m_original->resetToDefault(); +} + LegacyCustomSettingToV3Node* LegacyCustomSettingToV3Node::create(std::shared_ptr original, float width) { auto ret = new LegacyCustomSettingToV3Node(); if (ret && ret->init(original, width)) { @@ -512,13 +763,3 @@ LegacyCustomSettingToV3Node* LegacyCustomSettingToV3Node::create(std::shared_ptr CC_SAFE_DELETE(ret); return nullptr; } - -bool LegacyCustomSettingToV3Node::hasUncommittedChanges() const { - return m_original->hasUncommittedChanges(); -} -bool LegacyCustomSettingToV3Node::hasNonDefaultValue() const { - return m_original->hasNonDefaultValue(); -} -void LegacyCustomSettingToV3Node::resetToDefault() { - m_original->resetToDefault(); -} diff --git a/loader/src/loader/SettingNodeV3.hpp b/loader/src/loader/SettingNodeV3.hpp index ca1753e1..419522ba 100644 --- a/loader/src/loader/SettingNodeV3.hpp +++ b/loader/src/loader/SettingNodeV3.hpp @@ -20,7 +20,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -32,7 +32,6 @@ protected: bool init(std::shared_ptr setting, float width); void onCommit() override; - void onToggle(CCObject*); public: @@ -40,39 +39,59 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; class IntSettingNodeV3 : public SettingNodeV3 { protected: + TextInput* m_input; + Slider* m_slider; + bool init(std::shared_ptr setting, float width); + void updateState() override; + void onCommit() override; + void onArrow(CCObject* sender); + void onSlider(CCObject*); + + int64_t getCurrentValue() const; + void setCurrentValue(int64_t value); public: static IntSettingNodeV3* create(std::shared_ptr setting, float width); bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; class FloatSettingNodeV3 : public SettingNodeV3 { protected: + TextInput* m_input; + Slider* m_slider; + bool init(std::shared_ptr setting, float width); + void updateState() override; + void onCommit() override; + void onArrow(CCObject* sender); + void onSlider(CCObject*); + + double getCurrentValue() const; + void setCurrentValue(double value); public: static FloatSettingNodeV3* create(std::shared_ptr setting, float width); bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -88,7 +107,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -104,7 +123,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -120,7 +139,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -136,7 +155,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -152,7 +171,7 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; std::shared_ptr getSetting() const; }; @@ -172,5 +191,5 @@ public: bool hasUncommittedChanges() const override; bool hasNonDefaultValue() const override; - void resetToDefault() override; + void onResetToDefault() override; }; diff --git a/loader/src/loader/SettingV3.cpp b/loader/src/loader/SettingV3.cpp index 119821d8..d44574a7 100644 --- a/loader/src/loader/SettingV3.cpp +++ b/loader/src/loader/SettingV3.cpp @@ -47,6 +47,9 @@ std::string SettingV3::getModID() const { std::optional SettingV3::getName() const { return m_impl->name; } +std::string SettingV3::getDisplayName() const { + return m_impl->name.value_or(m_impl->key); +} std::optional SettingV3::getDescription() const { return m_impl->description; } @@ -217,11 +220,11 @@ public: struct { // 0 means not enabled - size_t arrowStepSize; - size_t bigArrowStepSize; - bool sliderEnabled; + size_t arrowStepSize = 1; + size_t bigArrowStepSize = 5; + bool sliderEnabled = true; std::optional sliderSnap; - bool textInputEnabled; + bool textInputEnabled = true; } controls; }; @@ -247,6 +250,18 @@ Result> IntSettingV3::parse(std::string const& key controls.has("slider").into(ret->m_impl->controls.sliderEnabled); controls.has("slider-step").into(ret->m_impl->controls.sliderSnap); controls.has("input").into(ret->m_impl->controls.textInputEnabled); + // Without "min" or "max" slider makes no sense + if (!ret->m_impl->minValue || !ret->m_impl->maxValue) { + if (ret->m_impl->controls.sliderEnabled) { + log::warn( + "Setting '{}' has \"controls.slider\" enabled but doesn't " + "have both \"min\" and \"max\" defined - the slider has " + "been force-disabled!", + key + ); + } + ret->m_impl->controls.sliderEnabled = false; + } controls.checkUnknownKeys(); } @@ -381,6 +396,18 @@ Result> FloatSettingV3::parse(std::string const& controls.has("slider").into(ret->m_impl->controls.sliderEnabled); controls.has("slider-step").into(ret->m_impl->controls.sliderSnap); controls.has("input").into(ret->m_impl->controls.textInputEnabled); + // Without "min" or "max" slider makes no sense + if (!ret->m_impl->minValue || !ret->m_impl->maxValue) { + if (ret->m_impl->controls.sliderEnabled) { + log::warn( + "Setting '{}' has \"controls.slider\" enabled but doesn't " + "have both \"min\" and \"max\" defined - the slider has " + "been force-disabled!", + key + ); + } + ret->m_impl->controls.sliderEnabled = false; + } controls.checkUnknownKeys(); } diff --git a/loader/src/ui/mods/settings/ModSettingsPopup.cpp b/loader/src/ui/mods/settings/ModSettingsPopup.cpp index 020ca261..5c5fdf72 100644 --- a/loader/src/ui/mods/settings/ModSettingsPopup.cpp +++ b/loader/src/ui/mods/settings/ModSettingsPopup.cpp @@ -132,6 +132,8 @@ void ModSettingsPopup::onResetAll(CCObject*) { } void ModSettingsPopup::updateState() { + m_applyBtnSpr->setCascadeColorEnabled(true); + m_applyBtnSpr->setCascadeOpacityEnabled(true); if (this->hasUncommitted()) { m_applyBtnSpr->setColor(ccWHITE); m_applyBtnSpr->setOpacity(255);