diff --git a/loader/include/Geode/loader/SettingV3.hpp b/loader/include/Geode/loader/SettingV3.hpp index a5a09128..6021450f 100644 --- a/loader/include/Geode/loader/SettingV3.hpp +++ b/loader/include/Geode/loader/SettingV3.hpp @@ -431,6 +431,10 @@ namespace geode { virtual bool hasUncommittedChanges() const = 0; virtual bool hasNonDefaultValue() const = 0; + // Can be overridden by the setting itself + // Can / should be used to do alternating BG + void setBGColor(cocos2d::ccColor4B const& color); + cocos2d::CCLabelBMFont* getNameLabel() const; cocos2d::CCMenu* getNameMenu() const; cocos2d::CCMenu* getButtonMenu() const; diff --git a/loader/src/loader/SettingNodeV3.cpp b/loader/src/loader/SettingNodeV3.cpp index b2703d93..927ec27a 100644 --- a/loader/src/loader/SettingNodeV3.cpp +++ b/loader/src/loader/SettingNodeV3.cpp @@ -1,5 +1,7 @@ #include "SettingNodeV3.hpp" #include +#include +#include class SettingNodeSizeChangeEventV3::Impl final { public: @@ -36,10 +38,14 @@ bool SettingNodeValueChangeEventV3::isCommit() const { class SettingNodeV3::Impl final { public: std::shared_ptr setting; + CCLayerColor* bg; CCLabelBMFont* nameLabel; CCMenu* nameMenu; CCMenu* buttonMenu; CCMenuItemSpriteExtra* resetButton; + ButtonSprite* restartRequiredLabel; + ccColor4B bgColor = ccc4(0, 0, 0, 0); + bool committed = false; }; bool SettingNodeV3::init(std::shared_ptr setting, float width) { @@ -49,6 +55,12 @@ bool SettingNodeV3::init(std::shared_ptr setting, float width) { m_impl = std::make_shared(); m_impl->setting = setting; + m_impl->bg = CCLayerColor::create({ 0, 0, 0, 0 }); + m_impl->bg->setContentSize({ width, 0 }); + m_impl->bg->ignoreAnchorPointForPosition(false); + m_impl->bg->setAnchorPoint(ccp(.5f, .5f)); + this->addChildAtPosition(m_impl->bg, Anchor::Center); + m_impl->nameMenu = CCMenu::create(); m_impl->nameMenu->setContentWidth(width / 2 + 25); @@ -56,6 +68,16 @@ bool SettingNodeV3::init(std::shared_ptr setting, float width) { m_impl->nameLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .4f)->setScalePriority(1)); m_impl->nameMenu->addChild(m_impl->nameLabel); + m_impl->restartRequiredLabel = createGeodeTagLabel( + "Restart Required", + {{ + to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)), + to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr)) + }} + ); + m_impl->restartRequiredLabel->setScale(.25f); + this->addChildAtPosition(m_impl->restartRequiredLabel, Anchor::Left, ccp(10, -10), ccp(0, .5f)); + if (setting->getDescription()) { auto descSpr = CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png"); descSpr->setScale(.5f); @@ -88,8 +110,19 @@ bool SettingNodeV3::init(std::shared_ptr setting, float width) { } void SettingNodeV3::updateState() { - this->getNameLabel()->setColor(this->hasUncommittedChanges() ? ccc3(17, 221, 0) : ccWHITE); + m_impl->nameLabel->setColor(this->hasUncommittedChanges() ? ccc3(17, 221, 0) : ccWHITE); m_impl->resetButton->setVisible(this->hasNonDefaultValue()); + + m_impl->bg->setColor(to3B(m_impl->bgColor)); + m_impl->bg->setOpacity(m_impl->bgColor.a); + + m_impl->restartRequiredLabel->setVisible(false); + if (m_impl->setting->requiresRestart() && (this->hasUncommittedChanges() || m_impl->committed)) { + m_impl->restartRequiredLabel->setVisible(true); + m_impl->bg->setColor("mod-list-restart-required-label-bg"_cc3b); + m_impl->bg->setOpacity(75); + } + m_impl->nameMenu->updateLayout(); } @@ -119,12 +152,18 @@ void SettingNodeV3::onReset(CCObject*) { ); } +void SettingNodeV3::setBGColor(ccColor4B const& color) { + m_impl->bgColor = color; + this->updateState(); +} + void SettingNodeV3::markChanged() { this->updateState(); SettingNodeValueChangeEventV3(false).post(); } void SettingNodeV3::commit() { this->onCommit(); + m_impl->committed = true; this->updateState(); SettingNodeValueChangeEventV3(true).post(); } @@ -137,6 +176,7 @@ void SettingNodeV3::resetToDefault() { void SettingNodeV3::setContentSize(CCSize const& size) { CCNode::setContentSize(size); + m_impl->bg->setContentSize(size); this->updateLayout(); SettingNodeSizeChangeEventV3(this).post(); } diff --git a/loader/src/ui/mods/settings/ModSettingsPopup.cpp b/loader/src/ui/mods/settings/ModSettingsPopup.cpp index 5c5fdf72..4b618b57 100644 --- a/loader/src/ui/mods/settings/ModSettingsPopup.cpp +++ b/loader/src/ui/mods/settings/ModSettingsPopup.cpp @@ -23,12 +23,9 @@ bool ModSettingsPopup::setup(Mod* mod) { auto layer = ScrollLayer::create(layerSize); layer->setTouchEnabled(true); - bool hasBG = false; + bool bg = false; for (auto& key : mod->getSettingKeys()) { - hasBG = !hasBG; - - auto bg = CCLayerColor::create({ 0, 0, 0, 50 }); - bg->setOpacity(hasBG ? 60 : 20); + bg = !bg; SettingNodeV3* node; if (auto sett = mod->getSettingV3(key)) { @@ -38,18 +35,15 @@ bool ModSettingsPopup::setup(Mod* mod) { // todo: placeholder node continue; } + node->setBGColor(ccc4(0, 0, 0, bg ? 60 : 20)); - bg->setContentSize(node->getScaledContentSize()); - bg->addChildAtPosition(node, Anchor::Center, ccp(0, 0), ccp(.5f, .5f)); - // auto separator = CCLayerColor::create({ 0, 0, 0, 50 }, layerSize.width, 1.f); - // separator->setOpacity(hasBG ? 100 : 50); + // separator->setOpacity(bg ? 100 : 50); // separator->ignoreAnchorPointForPosition(false); // bg->addChildAtPosition(separator, Anchor::Bottom, ccp(0, 0), ccp(.5f, .5f)); m_settings.push_back(node); - - layer->m_contentLayer->addChild(bg); + layer->m_contentLayer->addChild(node); } layer->m_contentLayer->setLayout( ColumnLayout::create()