mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-26 01:18:01 -05:00
add settings searching :3
This commit is contained in:
parent
ab9654a596
commit
8e38551ea4
2 changed files with 84 additions and 10 deletions
|
@ -7,6 +7,32 @@
|
||||||
#include <Geode/utils/cocos.hpp>
|
#include <Geode/utils/cocos.hpp>
|
||||||
#include <Geode/ui/General.hpp>
|
#include <Geode/ui/General.hpp>
|
||||||
#include <loader/SettingNodeV3.hpp>
|
#include <loader/SettingNodeV3.hpp>
|
||||||
|
// needed for weightedFuzzyMatch
|
||||||
|
#include <ui/mods/sources/ModListSource.hpp>
|
||||||
|
|
||||||
|
static bool matchSearch(SettingNodeV3* node, std::string const& query) {
|
||||||
|
if (typeinfo_cast<TitleSettingNodeV3*>(node)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool addToList = false;
|
||||||
|
auto setting = node->getSetting();
|
||||||
|
double weighted = 0;
|
||||||
|
if (auto name = setting->getName()) {
|
||||||
|
addToList |= weightedFuzzyMatch(setting->getKey(), query, 0.5, weighted);
|
||||||
|
addToList |= weightedFuzzyMatch(*name, query, 1, weighted);
|
||||||
|
}
|
||||||
|
// If there's no name, give full weight to key
|
||||||
|
else {
|
||||||
|
addToList |= weightedFuzzyMatch(setting->getKey(), query, 1, weighted);
|
||||||
|
}
|
||||||
|
if (auto desc = setting->getDescription()) {
|
||||||
|
addToList |= weightedFuzzyMatch(*desc, query, 0.02, weighted);
|
||||||
|
}
|
||||||
|
if (weighted < 2) {
|
||||||
|
addToList = false;
|
||||||
|
}
|
||||||
|
return addToList;
|
||||||
|
}
|
||||||
|
|
||||||
bool ModSettingsPopup::setup(Mod* mod) {
|
bool ModSettingsPopup::setup(Mod* mod) {
|
||||||
m_noElasticity = true;
|
m_noElasticity = true;
|
||||||
|
@ -20,10 +46,34 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
||||||
|
|
||||||
auto layerBG = CCLayerColor::create({ 0, 0, 0, 75 });
|
auto layerBG = CCLayerColor::create({ 0, 0, 0, 75 });
|
||||||
layerBG->setContentSize(layerSize);
|
layerBG->setContentSize(layerSize);
|
||||||
m_mainLayer->addChildAtPosition(layerBG, Anchor::Center, -layerSize / 2);
|
layerBG->ignoreAnchorPointForPosition(false);
|
||||||
|
m_mainLayer->addChildAtPosition(layerBG, Anchor::Center);
|
||||||
|
|
||||||
auto layer = ScrollLayer::create(layerSize);
|
auto searchContainer = CCMenu::create();
|
||||||
layer->setTouchEnabled(true);
|
searchContainer->setContentSize({ layerSize.width, 30 });
|
||||||
|
|
||||||
|
m_searchInput = TextInput::create((layerSize.width - 15) / .7f - 40, "Search Settings...");
|
||||||
|
m_searchInput->setTextAlign(TextInputAlign::Left);
|
||||||
|
m_searchInput->setScale(.7f);
|
||||||
|
m_searchInput->setCallback([this](auto const&) {
|
||||||
|
this->updateState();
|
||||||
|
m_list->moveToTop();
|
||||||
|
});
|
||||||
|
m_searchInput->setID("search-input");
|
||||||
|
searchContainer->addChildAtPosition(m_searchInput, Anchor::Left, ccp(7.5f, 0), ccp(0, .5f));
|
||||||
|
|
||||||
|
auto searchClearSpr = GeodeSquareSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png");
|
||||||
|
searchClearSpr->setScale(.45f);
|
||||||
|
m_searchClearBtn = CCMenuItemSpriteExtra::create(
|
||||||
|
searchClearSpr, this, menu_selector(ModSettingsPopup::onClearSearch)
|
||||||
|
);
|
||||||
|
m_searchClearBtn->setID("clear-search-button");
|
||||||
|
searchContainer->addChildAtPosition(m_searchClearBtn, Anchor::Right, ccp(-20, 0));
|
||||||
|
|
||||||
|
layerBG->addChildAtPosition(searchContainer, Anchor::Top, ccp(0, 0), ccp(.5f, 1));
|
||||||
|
|
||||||
|
m_list = ScrollLayer::create(layerSize - ccp(0, searchContainer->getContentHeight()));
|
||||||
|
m_list->setTouchEnabled(true);
|
||||||
|
|
||||||
bool bg = false;
|
bool bg = false;
|
||||||
for (auto& key : mod->getSettingKeys()) {
|
for (auto& key : mod->getSettingKeys()) {
|
||||||
|
@ -44,9 +94,9 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
||||||
// bg->addChildAtPosition(separator, Anchor::Bottom, ccp(0, 0), ccp(.5f, .5f));
|
// bg->addChildAtPosition(separator, Anchor::Bottom, ccp(0, 0), ccp(.5f, .5f));
|
||||||
|
|
||||||
m_settings.push_back(node);
|
m_settings.push_back(node);
|
||||||
layer->m_contentLayer->addChild(node);
|
m_list->m_contentLayer->addChild(node);
|
||||||
}
|
}
|
||||||
layer->m_contentLayer->setLayout(
|
m_list->m_contentLayer->setLayout(
|
||||||
ColumnLayout::create()
|
ColumnLayout::create()
|
||||||
->setAxisReverse(true)
|
->setAxisReverse(true)
|
||||||
->setAutoGrowAxis(layerSize.height)
|
->setAutoGrowAxis(layerSize.height)
|
||||||
|
@ -54,13 +104,13 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
||||||
->setAxisAlignment(AxisAlignment::End)
|
->setAxisAlignment(AxisAlignment::End)
|
||||||
->setGap(0)
|
->setGap(0)
|
||||||
);
|
);
|
||||||
layer->moveToTop();
|
m_list->moveToTop();
|
||||||
|
|
||||||
layerBG->addChild(layer);
|
layerBG->addChildAtPosition(m_list, Anchor::BottomLeft);
|
||||||
|
|
||||||
// layer borders
|
// layer borders
|
||||||
|
|
||||||
m_mainLayer->addChildAtPosition(createGeodeListBorders({layerSize.width, layerSize.height - 2}), Anchor::Center);
|
m_mainLayer->addChildAtPosition(createGeodeListBorders(layerSize), Anchor::Center);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
|
|
||||||
|
@ -174,8 +224,16 @@ void ModSettingsPopup::onOpenConfigDirectory(CCObject*) {
|
||||||
file::openFolder(m_mod->getConfigDir());
|
file::openFolder(m_mod->getConfigDir());
|
||||||
this->updateState();
|
this->updateState();
|
||||||
}
|
}
|
||||||
|
void ModSettingsPopup::onClearSearch(CCObject*) {
|
||||||
|
m_searchInput->setString("");
|
||||||
|
this->updateState();
|
||||||
|
m_list->moveToTop();
|
||||||
|
}
|
||||||
|
|
||||||
void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
||||||
|
auto search = m_searchInput->getString();
|
||||||
|
auto hasSearch = !search.empty();
|
||||||
|
|
||||||
m_restartBtn->setVisible(ModSettingsManager::from(m_mod)->restartRequired());
|
m_restartBtn->setVisible(ModSettingsManager::from(m_mod)->restartRequired());
|
||||||
m_applyMenu->updateLayout();
|
m_applyMenu->updateLayout();
|
||||||
|
|
||||||
|
@ -185,8 +243,12 @@ void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
||||||
m_openConfigDirBtnSpr->setColor(configDirExists ? ccWHITE : ccGRAY);
|
m_openConfigDirBtnSpr->setColor(configDirExists ? ccWHITE : ccGRAY);
|
||||||
m_openConfigDirBtnSpr->setOpacity(configDirExists ? 255 : 155);
|
m_openConfigDirBtnSpr->setOpacity(configDirExists ? 255 : 155);
|
||||||
|
|
||||||
// Update all settings with "enable-if" schemes
|
// Update search visibility + all settings with "enable-if" schemes
|
||||||
for (auto& sett : m_settings) {
|
for (auto& sett : m_settings) {
|
||||||
|
sett->removeFromParent();
|
||||||
|
if (!hasSearch || matchSearch(sett, search)) {
|
||||||
|
m_list->m_contentLayer->addChild(sett);
|
||||||
|
}
|
||||||
// Avoid infinite loops
|
// Avoid infinite loops
|
||||||
if (sett == invoker) {
|
if (sett == invoker) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -195,6 +257,7 @@ void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
||||||
sett->updateState(nullptr);
|
sett->updateState(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_list->m_contentLayer->updateLayout();
|
||||||
|
|
||||||
m_applyBtnSpr->setCascadeColorEnabled(true);
|
m_applyBtnSpr->setCascadeColorEnabled(true);
|
||||||
m_applyBtnSpr->setCascadeOpacityEnabled(true);
|
m_applyBtnSpr->setCascadeOpacityEnabled(true);
|
||||||
|
@ -208,6 +271,13 @@ void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
||||||
m_applyBtnSpr->setOpacity(155);
|
m_applyBtnSpr->setOpacity(155);
|
||||||
m_applyBtn->setEnabled(false);
|
m_applyBtn->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto clearSpr = static_cast<GeodeSquareSprite*>(m_searchClearBtn->getNormalImage());
|
||||||
|
m_searchClearBtn->setEnabled(hasSearch);
|
||||||
|
clearSpr->setColor(hasSearch ? ccWHITE : ccGRAY);
|
||||||
|
clearSpr->setOpacity(hasSearch ? 255 : 90);
|
||||||
|
clearSpr->getTopSprite()->setColor(hasSearch ? ccWHITE : ccGRAY);
|
||||||
|
clearSpr->getTopSprite()->setOpacity(hasSearch ? 255 : 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModSettingsPopup::hasUncommitted() const {
|
bool ModSettingsPopup::hasUncommitted() const {
|
||||||
|
|
|
@ -10,12 +10,15 @@ using namespace geode::prelude;
|
||||||
class ModSettingsPopup : public GeodePopup<Mod*> {
|
class ModSettingsPopup : public GeodePopup<Mod*> {
|
||||||
protected:
|
protected:
|
||||||
Mod* m_mod;
|
Mod* m_mod;
|
||||||
std::vector<SettingNodeV3*> m_settings;
|
ScrollLayer* m_list;
|
||||||
|
std::vector<Ref<SettingNodeV3>> m_settings;
|
||||||
CCMenu* m_applyMenu;
|
CCMenu* m_applyMenu;
|
||||||
CCMenuItemSpriteExtra* m_applyBtn;
|
CCMenuItemSpriteExtra* m_applyBtn;
|
||||||
CCMenuItemSpriteExtra* m_restartBtn;
|
CCMenuItemSpriteExtra* m_restartBtn;
|
||||||
ButtonSprite* m_applyBtnSpr;
|
ButtonSprite* m_applyBtnSpr;
|
||||||
IconButtonSprite* m_openConfigDirBtnSpr;
|
IconButtonSprite* m_openConfigDirBtnSpr;
|
||||||
|
TextInput* m_searchInput;
|
||||||
|
CCMenuItemSpriteExtra* m_searchClearBtn;
|
||||||
EventListener<EventFilter<SettingNodeValueChangeEventV3>> m_changeListener;
|
EventListener<EventFilter<SettingNodeValueChangeEventV3>> m_changeListener;
|
||||||
|
|
||||||
bool setup(Mod* mod) override;
|
bool setup(Mod* mod) override;
|
||||||
|
@ -27,6 +30,7 @@ protected:
|
||||||
void onResetAll(CCObject*);
|
void onResetAll(CCObject*);
|
||||||
void onOpenSaveDirectory(CCObject*);
|
void onOpenSaveDirectory(CCObject*);
|
||||||
void onOpenConfigDirectory(CCObject*);
|
void onOpenConfigDirectory(CCObject*);
|
||||||
|
void onClearSearch(CCObject*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ModSettingsPopup* create(Mod* mod);
|
static ModSettingsPopup* create(Mod* mod);
|
||||||
|
|
Loading…
Reference in a new issue