mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
string setting nodes + move number setting nodes to a shared class + legacy custom setting nodes proven to work
This commit is contained in:
parent
85e7b5e3ab
commit
dc6637e130
3 changed files with 244 additions and 354 deletions
|
@ -1,27 +1,6 @@
|
||||||
#include "SettingNodeV3.hpp"
|
#include "SettingNodeV3.hpp"
|
||||||
#include <Geode/loader/SettingNode.hpp>
|
#include <Geode/loader/SettingNode.hpp>
|
||||||
|
|
||||||
template<class T>
|
|
||||||
static float valueToSlider(std::shared_ptr<T> 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<float>(clamp(static_cast<double>(value - min) / range, 0.0, 1.0));
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
static typename T::ValueType valueFromSlider(std::shared_ptr<T> 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<typename T::ValueType>(num * range + min);
|
|
||||||
if (auto step = setting->getSliderSnap()) {
|
|
||||||
value = static_cast<typename T::ValueType>(
|
|
||||||
round(value / *step) * (*step)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SettingNodeSizeChangeEventV3::Impl final {
|
class SettingNodeSizeChangeEventV3::Impl final {
|
||||||
public:
|
public:
|
||||||
SettingNodeV3* node;
|
SettingNodeV3* node;
|
||||||
|
@ -71,7 +50,7 @@ bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
||||||
m_impl->setting = setting;
|
m_impl->setting = setting;
|
||||||
|
|
||||||
m_impl->nameMenu = CCMenu::create();
|
m_impl->nameMenu = CCMenu::create();
|
||||||
m_impl->nameMenu->setContentWidth(width / 2 - 20);
|
m_impl->nameMenu->setContentWidth(width / 2 + 25);
|
||||||
|
|
||||||
m_impl->nameLabel = CCLabelBMFont::create(setting->getDisplayName().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->nameLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .4f)->setScalePriority(1));
|
||||||
|
@ -97,8 +76,8 @@ bool SettingNodeV3::init(std::shared_ptr<SettingV3> setting, float width) {
|
||||||
this->addChildAtPosition(m_impl->nameMenu, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
this->addChildAtPosition(m_impl->nameMenu, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
||||||
|
|
||||||
m_impl->buttonMenu = CCMenu::create();
|
m_impl->buttonMenu = CCMenu::create();
|
||||||
m_impl->buttonMenu->setContentWidth(width / 2 - 20);
|
m_impl->buttonMenu->setContentSize({ width / 2 - 55, 30 });
|
||||||
m_impl->buttonMenu->setLayout(RowLayout::create()->setAxisAlignment(AxisAlignment::End));
|
m_impl->buttonMenu->setLayout(AnchorLayout::create());
|
||||||
this->addChildAtPosition(m_impl->buttonMenu, Anchor::Right, ccp(-10, 0), ccp(1, .5f));
|
this->addChildAtPosition(m_impl->buttonMenu, Anchor::Right, ccp(-10, 0), ccp(1, .5f));
|
||||||
|
|
||||||
this->setAnchorPoint({ .5f, .5f });
|
this->setAnchorPoint({ .5f, .5f });
|
||||||
|
@ -120,7 +99,7 @@ void SettingNodeV3::onDescription(CCObject*) {
|
||||||
title.c_str(),
|
title.c_str(),
|
||||||
m_impl->setting->getDescription().value_or("No description provided"),
|
m_impl->setting->getDescription().value_or("No description provided"),
|
||||||
"OK", nullptr,
|
"OK", nullptr,
|
||||||
clamp(title.size() * 16, 240, 400)
|
clamp(title.size() * 16, 300, 400)
|
||||||
)->show();
|
)->show();
|
||||||
}
|
}
|
||||||
void SettingNodeV3::onReset(CCObject*) {
|
void SettingNodeV3::onReset(CCObject*) {
|
||||||
|
@ -228,8 +207,10 @@ bool BoolSettingNodeV3::init(std::shared_ptr<BoolSettingV3> setting, float width
|
||||||
m_toggle->m_offButton->getNormalImage()->setPosition(ccp(25, 25) / 2);
|
m_toggle->m_offButton->getNormalImage()->setPosition(ccp(25, 25) / 2);
|
||||||
m_toggle->m_notClickable = true;
|
m_toggle->m_notClickable = true;
|
||||||
m_toggle->toggle(setting->getValue());
|
m_toggle->toggle(setting->getValue());
|
||||||
this->getButtonMenu()->addChild(m_toggle);
|
this->getButtonMenu()->addChildAtPosition(m_toggle, Anchor::Right, ccp(-10, 0));
|
||||||
this->getButtonMenu()->updateLayout();
|
|
||||||
|
this->getNameMenu()->setContentWidth(width - 50);
|
||||||
|
this->getNameMenu()->updateLayout();
|
||||||
|
|
||||||
this->updateState();
|
this->updateState();
|
||||||
|
|
||||||
|
@ -268,303 +249,75 @@ BoolSettingNodeV3* BoolSettingNodeV3::create(std::shared_ptr<BoolSettingV3> sett
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntSettingNodeV3
|
|
||||||
|
|
||||||
bool IntSettingNodeV3::init(std::shared_ptr<IntSettingV3> 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");
|
|
||||||
|
|
||||||
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::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<int64_t>(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<IntSettingV3> IntSettingNodeV3::getSetting() const {
|
|
||||||
return std::static_pointer_cast<IntSettingV3>(SettingNodeV3::getSetting());
|
|
||||||
}
|
|
||||||
|
|
||||||
IntSettingNodeV3* IntSettingNodeV3::create(std::shared_ptr<IntSettingV3> setting, float width) {
|
|
||||||
auto ret = new IntSettingNodeV3();
|
|
||||||
if (ret && ret->init(setting, width)) {
|
|
||||||
ret->autorelease();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
CC_SAFE_DELETE(ret);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FloatSettingNodeV3
|
|
||||||
|
|
||||||
bool FloatSettingNodeV3::init(std::shared_ptr<FloatSettingV3> 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");
|
|
||||||
|
|
||||||
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::updateState() {
|
|
||||||
SettingNodeV3::updateState();
|
|
||||||
m_slider->m_touchLogic->m_thumb->setValue(valueToSlider(
|
|
||||||
this->getSetting(), this->getCurrentValue()
|
|
||||||
));
|
|
||||||
m_slider->updateBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
double FloatSettingNodeV3::getCurrentValue() const {
|
|
||||||
return numFromString<double>(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<FloatSettingV3> FloatSettingNodeV3::getSetting() const {
|
|
||||||
return std::static_pointer_cast<FloatSettingV3>(SettingNodeV3::getSetting());
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatSettingNodeV3* FloatSettingNodeV3::create(std::shared_ptr<FloatSettingV3> setting, float width) {
|
|
||||||
auto ret = new FloatSettingNodeV3();
|
|
||||||
if (ret && ret->init(setting, width)) {
|
|
||||||
ret->autorelease();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
CC_SAFE_DELETE(ret);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSettingNodeV3
|
// StringSettingNodeV3
|
||||||
|
|
||||||
bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float width) {
|
bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float width) {
|
||||||
if (!SettingNodeV3::init(setting, width))
|
if (!SettingNodeV3::init(setting, width))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// todo
|
m_input = TextInput::create(width / 2 - 50, "Num");
|
||||||
|
m_input->setCallback([this](auto const&) {
|
||||||
|
this->markChanged();
|
||||||
|
});
|
||||||
|
m_input->setScale(.7f);
|
||||||
|
m_input->setString(this->getSetting()->getValue());
|
||||||
|
this->getButtonMenu()->addChildAtPosition(m_input, Anchor::Center);
|
||||||
|
|
||||||
|
if (setting->getEnumOptions()) {
|
||||||
|
m_input->getBGSprite()->setVisible(false);
|
||||||
|
m_input->setEnabled(false);
|
||||||
|
m_input->getInputNode()->m_placeholderLabel->setOpacity(255);
|
||||||
|
m_input->getInputNode()->m_placeholderLabel->setColor(ccWHITE);
|
||||||
|
|
||||||
|
auto arrowLeftSpr = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png");
|
||||||
|
arrowLeftSpr->setFlipX(true);
|
||||||
|
arrowLeftSpr->setScale(.4f);
|
||||||
|
auto arrowLeftBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
arrowLeftSpr, this, menu_selector(StringSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
arrowLeftBtn->setTag(-1);
|
||||||
|
this->getButtonMenu()->addChildAtPosition(arrowLeftBtn, Anchor::Left, ccp(5, 0));
|
||||||
|
|
||||||
|
auto arrowRightSpr = CCSprite::createWithSpriteFrameName("navArrowBtn_001.png");
|
||||||
|
arrowRightSpr->setScale(.4f);
|
||||||
|
auto arrowRightBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
arrowRightSpr, this, menu_selector(StringSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
arrowRightBtn->setTag(1);
|
||||||
|
this->getButtonMenu()->addChildAtPosition(arrowRightBtn, Anchor::Right, ccp(-5, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->updateState();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringSettingNodeV3::onCommit() {}
|
void StringSettingNodeV3::onArrow(CCObject* sender) {
|
||||||
|
auto options = *this->getSetting()->getEnumOptions();
|
||||||
|
auto index = ranges::indexOf(options, m_input->getString()).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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringSettingNodeV3::onCommit() {
|
||||||
|
this->getSetting()->setValue(m_input->getString());
|
||||||
|
}
|
||||||
|
|
||||||
bool StringSettingNodeV3::hasUncommittedChanges() const {
|
bool StringSettingNodeV3::hasUncommittedChanges() const {
|
||||||
return false;
|
return m_input->getString() != this->getSetting()->getValue();
|
||||||
}
|
}
|
||||||
bool StringSettingNodeV3::hasNonDefaultValue() const {
|
bool StringSettingNodeV3::hasNonDefaultValue() const {
|
||||||
return false;
|
return m_input->getString() != this->getSetting()->getDefaultValue();
|
||||||
|
}
|
||||||
|
void StringSettingNodeV3::onResetToDefault() {
|
||||||
|
m_input->setString(this->getSetting()->getDefaultValue());
|
||||||
}
|
}
|
||||||
void StringSettingNodeV3::onResetToDefault() {}
|
|
||||||
|
|
||||||
std::shared_ptr<StringSettingV3> StringSettingNodeV3::getSetting() const {
|
std::shared_ptr<StringSettingV3> StringSettingNodeV3::getSetting() const {
|
||||||
return std::static_pointer_cast<StringSettingV3>(SettingNodeV3::getSetting());
|
return std::static_pointer_cast<StringSettingV3>(SettingNodeV3::getSetting());
|
||||||
|
@ -733,13 +486,24 @@ bool LegacyCustomSettingToV3Node::init(std::shared_ptr<LegacyCustomSettingV3> or
|
||||||
if (!SettingNodeV3::init(original, width))
|
if (!SettingNodeV3::init(original, width))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
this->getNameMenu()->setVisible(false);
|
||||||
|
this->getButtonMenu()->setVisible(false);
|
||||||
|
|
||||||
m_original = original->getValue()->createNode(width);
|
m_original = original->getValue()->createNode(width);
|
||||||
|
m_original->setDelegate(this);
|
||||||
this->setContentSize({ width, m_original->getContentHeight() });
|
this->setContentSize({ width, m_original->getContentHeight() });
|
||||||
this->addChildAtPosition(m_original, Anchor::Center);
|
this->addChildAtPosition(m_original, Anchor::BottomLeft, ccp(0, 0), ccp(0, 0));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LegacyCustomSettingToV3Node::settingValueChanged(SettingNode*) {
|
||||||
|
SettingNodeValueChangeEventV3(false).post();
|
||||||
|
}
|
||||||
|
void LegacyCustomSettingToV3Node::settingValueCommitted(SettingNode*) {
|
||||||
|
SettingNodeValueChangeEventV3(true).post();
|
||||||
|
}
|
||||||
|
|
||||||
void LegacyCustomSettingToV3Node::onCommit() {
|
void LegacyCustomSettingToV3Node::onCommit() {
|
||||||
m_original->commit();
|
m_original->commit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Geode/loader/SettingV3.hpp>
|
#include <Geode/loader/SettingV3.hpp>
|
||||||
|
#include <Geode/loader/SettingNode.hpp>
|
||||||
#include <Geode/binding/CCMenuItemToggler.hpp>
|
#include <Geode/binding/CCMenuItemToggler.hpp>
|
||||||
|
|
||||||
using namespace geode::prelude;
|
using namespace geode::prelude;
|
||||||
|
@ -44,64 +45,182 @@ public:
|
||||||
std::shared_ptr<BoolSettingV3> getSetting() const;
|
std::shared_ptr<BoolSettingV3> getSetting() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IntSettingNodeV3 : public SettingNodeV3 {
|
template <class S>
|
||||||
|
class NumberSettingNodeV3 : public SettingNodeV3 {
|
||||||
protected:
|
protected:
|
||||||
|
using ValueType = typename S::ValueType;
|
||||||
|
|
||||||
TextInput* m_input;
|
TextInput* m_input;
|
||||||
Slider* m_slider;
|
Slider* m_slider;
|
||||||
|
|
||||||
bool init(std::shared_ptr<IntSettingV3> setting, float width);
|
float valueToSlider(ValueType value) {
|
||||||
|
auto min = this->getSetting()->getMinValue().value_or(-100);
|
||||||
|
auto max = this->getSetting()->getMaxValue().value_or(+100);
|
||||||
|
auto range = max - min;
|
||||||
|
return static_cast<float>(clamp(static_cast<double>(value - min) / range, 0.0, 1.0));
|
||||||
|
}
|
||||||
|
ValueType valueFromSlider(float num) {
|
||||||
|
auto min = this->getSetting()->getMinValue().value_or(-100);
|
||||||
|
auto max = this->getSetting()->getMaxValue().value_or(+100);
|
||||||
|
auto range = max - min;
|
||||||
|
auto value = static_cast<ValueType>(num * range + min);
|
||||||
|
if (auto step = this->getSetting()->getSliderSnap()) {
|
||||||
|
value = static_cast<ValueType>(round(value / *step) * (*step));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
void updateState() override;
|
bool init(std::shared_ptr<S> setting, float width) {
|
||||||
|
if (!SettingNodeV3::init(setting, width))
|
||||||
|
return false;
|
||||||
|
|
||||||
void onCommit() override;
|
auto bigArrowLeftSpr = CCSprite::create();
|
||||||
void onArrow(CCObject* sender);
|
auto bigArrowLeftSpr1 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png");
|
||||||
void onSlider(CCObject*);
|
auto bigArrowLeftSpr2 = CCSprite::createWithSpriteFrameName("GJ_arrow_03_001.png");
|
||||||
|
|
||||||
int64_t getCurrentValue() const;
|
bigArrowLeftSpr->setContentSize(bigArrowLeftSpr1->getContentSize() + ccp(20, 0));
|
||||||
void setCurrentValue(int64_t value);
|
bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr2, Anchor::Center, ccp(10, 0));
|
||||||
|
bigArrowLeftSpr->addChildAtPosition(bigArrowLeftSpr1, Anchor::Center, ccp(-10, 0));
|
||||||
|
bigArrowLeftSpr->setScale(.3f);
|
||||||
|
|
||||||
|
auto bigArrowLeftBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
bigArrowLeftSpr, this, menu_selector(NumberSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
bigArrowLeftBtn->setTag(-setting->getBigArrowStepSize());
|
||||||
|
bigArrowLeftBtn->setVisible(setting->isBigArrowsEnabled());
|
||||||
|
this->getButtonMenu()->addChildAtPosition(bigArrowLeftBtn, Anchor::Left, ccp(5, 0));
|
||||||
|
|
||||||
|
auto arrowLeftSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png");
|
||||||
|
arrowLeftSpr->setScale(.5f);
|
||||||
|
auto arrowLeftBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
arrowLeftSpr, this, menu_selector(NumberSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
arrowLeftBtn->setTag(-setting->getArrowStepSize());
|
||||||
|
arrowLeftBtn->setVisible(setting->isArrowsEnabled());
|
||||||
|
this->getButtonMenu()->addChildAtPosition(arrowLeftBtn, Anchor::Left, ccp(22, 0));
|
||||||
|
|
||||||
|
m_input = TextInput::create(this->getButtonMenu()->getContentWidth() - 40, "Num");
|
||||||
|
m_input->setScale(.7f);
|
||||||
|
m_input->setCallback([this](auto const&) {
|
||||||
|
this->markChanged();
|
||||||
|
});
|
||||||
|
if (!setting->isInputEnabled()) {
|
||||||
|
m_input->getBGSprite()->setVisible(false);
|
||||||
|
m_input->setEnabled(false);
|
||||||
|
m_input->getInputNode()->m_placeholderLabel->setOpacity(255);
|
||||||
|
m_input->getInputNode()->m_placeholderLabel->setColor(ccWHITE);
|
||||||
|
}
|
||||||
|
this->getButtonMenu()->addChildAtPosition(m_input, Anchor::Center);
|
||||||
|
|
||||||
|
auto arrowRightSpr = CCSprite::createWithSpriteFrameName("GJ_arrow_01_001.png");
|
||||||
|
arrowRightSpr->setFlipX(true);
|
||||||
|
arrowRightSpr->setScale(.5f);
|
||||||
|
auto arrowRightBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
arrowRightSpr, this, menu_selector(NumberSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
arrowRightBtn->setTag(setting->getArrowStepSize());
|
||||||
|
arrowRightBtn->setVisible(setting->isArrowsEnabled());
|
||||||
|
this->getButtonMenu()->addChildAtPosition(arrowRightBtn, Anchor::Right, ccp(-22, 0));
|
||||||
|
|
||||||
|
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(.3f);
|
||||||
|
|
||||||
|
auto bigArrowRightBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
bigArrowRightSpr, this, menu_selector(NumberSettingNodeV3::onArrow)
|
||||||
|
);
|
||||||
|
bigArrowRightBtn->setTag(setting->getBigArrowStepSize());
|
||||||
|
bigArrowRightBtn->setVisible(setting->isBigArrowsEnabled());
|
||||||
|
this->getButtonMenu()->addChildAtPosition(bigArrowRightBtn, Anchor::Right, ccp(-5, 0));
|
||||||
|
|
||||||
|
if (setting->isSliderEnabled()) {
|
||||||
|
this->setContentHeight(45);
|
||||||
|
this->getButtonMenu()->updateAnchoredPosition(Anchor::Right, ccp(-10, 7));
|
||||||
|
|
||||||
|
m_slider = Slider::create(this, menu_selector(NumberSettingNodeV3::onSlider));
|
||||||
|
m_slider->setScale(.5f);
|
||||||
|
this->getButtonMenu()->addChildAtPosition(m_slider, Anchor::Center, ccp(0, -20), ccp(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setCurrentValue(setting->getValue());
|
||||||
|
this->updateState();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateState() override {
|
||||||
|
SettingNodeV3::updateState();
|
||||||
|
if (m_slider) {
|
||||||
|
m_slider->m_touchLogic->m_thumb->setValue(this->valueToSlider(this->getCurrentValue()));
|
||||||
|
m_slider->updateBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCommit() override {
|
||||||
|
this->getSetting()->setValue(this->getCurrentValue());
|
||||||
|
}
|
||||||
|
void onArrow(CCObject* sender) {
|
||||||
|
this->setCurrentValue(this->getCurrentValue() + sender->getTag());
|
||||||
|
}
|
||||||
|
void onSlider(CCObject*) {
|
||||||
|
this->setCurrentValue(this->valueFromSlider(m_slider->m_touchLogic->m_thumb->getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType getCurrentValue() const {
|
||||||
|
return numFromString<ValueType>(m_input->getString())
|
||||||
|
.value_or(this->getSetting()->getDefaultValue());
|
||||||
|
}
|
||||||
|
void setCurrentValue(ValueType value) {
|
||||||
|
m_input->setString(numToString(value));
|
||||||
|
this->markChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static IntSettingNodeV3* create(std::shared_ptr<IntSettingV3> setting, float width);
|
static NumberSettingNodeV3* create(std::shared_ptr<S> setting, float width) {
|
||||||
|
auto ret = new NumberSettingNodeV3();
|
||||||
|
if (ret && ret->init(setting, width)) {
|
||||||
|
ret->autorelease();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
CC_SAFE_DELETE(ret);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasUncommittedChanges() const override;
|
bool hasUncommittedChanges() const override {
|
||||||
bool hasNonDefaultValue() const override;
|
return this->getSetting()->getValue() != this->getCurrentValue();
|
||||||
void onResetToDefault() override;
|
}
|
||||||
|
bool hasNonDefaultValue() const override {
|
||||||
|
return this->getSetting()->getDefaultValue() != this->getCurrentValue();
|
||||||
|
}
|
||||||
|
void onResetToDefault() override {
|
||||||
|
this->setCurrentValue(this->getSetting()->getDefaultValue());
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<IntSettingV3> getSetting() const;
|
std::shared_ptr<S> getSetting() const {
|
||||||
|
return std::static_pointer_cast<S>(SettingNodeV3::getSetting());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatSettingNodeV3 : public SettingNodeV3 {
|
using IntSettingNodeV3 = NumberSettingNodeV3<IntSettingV3>;
|
||||||
protected:
|
using FloatSettingNodeV3 = NumberSettingNodeV3<FloatSettingV3>;
|
||||||
TextInput* m_input;
|
|
||||||
Slider* m_slider;
|
|
||||||
|
|
||||||
bool init(std::shared_ptr<FloatSettingV3> 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<FloatSettingV3> setting, float width);
|
|
||||||
|
|
||||||
bool hasUncommittedChanges() const override;
|
|
||||||
bool hasNonDefaultValue() const override;
|
|
||||||
void onResetToDefault() override;
|
|
||||||
|
|
||||||
std::shared_ptr<FloatSettingV3> getSetting() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class StringSettingNodeV3 : public SettingNodeV3 {
|
class StringSettingNodeV3 : public SettingNodeV3 {
|
||||||
protected:
|
protected:
|
||||||
|
TextInput* m_input;
|
||||||
|
|
||||||
bool init(std::shared_ptr<StringSettingV3> setting, float width);
|
bool init(std::shared_ptr<StringSettingV3> setting, float width);
|
||||||
|
|
||||||
void onCommit() override;
|
void onCommit() override;
|
||||||
|
|
||||||
|
void onArrow(CCObject* sender);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static StringSettingNodeV3* create(std::shared_ptr<StringSettingV3> setting, float width);
|
static StringSettingNodeV3* create(std::shared_ptr<StringSettingV3> setting, float width);
|
||||||
|
|
||||||
|
@ -176,9 +295,10 @@ public:
|
||||||
std::shared_ptr<LegacyCustomSettingV3> getSetting() const;
|
std::shared_ptr<LegacyCustomSettingV3> getSetting() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If these classes do get exposed in headers, this SHOULD NOT BE EXPOSED!!!!!! DO NOT DO THAT!!!!
|
// If these classes do get exposed in headers,
|
||||||
|
// LegacyCustomSettingToV3Node SHOULD NOT BE EXPOSED!!!!!! DO NOT DO THAT!!!!
|
||||||
|
|
||||||
class LegacyCustomSettingToV3Node : public SettingNodeV3 {
|
class LegacyCustomSettingToV3Node : public SettingNodeV3, public SettingNodeDelegate {
|
||||||
protected:
|
protected:
|
||||||
SettingNode* m_original;
|
SettingNode* m_original;
|
||||||
|
|
||||||
|
@ -186,6 +306,9 @@ protected:
|
||||||
|
|
||||||
void onCommit() override;
|
void onCommit() override;
|
||||||
|
|
||||||
|
void settingValueChanged(SettingNode*) override;
|
||||||
|
void settingValueCommitted(SettingNode*) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static LegacyCustomSettingToV3Node* create(std::shared_ptr<LegacyCustomSettingV3> original, float width);
|
static LegacyCustomSettingToV3Node* create(std::shared_ptr<LegacyCustomSettingV3> original, float width);
|
||||||
|
|
||||||
|
|
|
@ -364,11 +364,11 @@ public:
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// 0 means not enabled
|
// 0 means not enabled
|
||||||
size_t arrowStepSize;
|
size_t arrowStepSize = 1;
|
||||||
size_t bigArrowStepSize;
|
size_t bigArrowStepSize = 5;
|
||||||
bool sliderEnabled;
|
bool sliderEnabled = true;
|
||||||
std::optional<double> sliderSnap;
|
std::optional<double> sliderSnap;
|
||||||
bool textInputEnabled;
|
bool textInputEnabled = true;
|
||||||
} controls;
|
} controls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -521,6 +521,9 @@ Result<std::shared_ptr<StringSettingV3>> StringSettingV3::parse(std::string cons
|
||||||
root.has("match").into(ret->m_impl->match);
|
root.has("match").into(ret->m_impl->match);
|
||||||
root.has("filter").into(ret->m_impl->filter);
|
root.has("filter").into(ret->m_impl->filter);
|
||||||
root.has("one-of").into(ret->m_impl->oneOf);
|
root.has("one-of").into(ret->m_impl->oneOf);
|
||||||
|
if (ret->m_impl->oneOf && ret->m_impl->oneOf->empty()) {
|
||||||
|
return Err("Setting '{}' in mod {} - \"one-of\" may not be empty!", key, modID);
|
||||||
|
}
|
||||||
|
|
||||||
root.checkUnknownKeys();
|
root.checkUnknownKeys();
|
||||||
return root.ok(ret);
|
return root.ok(ret);
|
||||||
|
|
Loading…
Reference in a new issue