From 2d0bbebfef05a559c15ff882d6b3780742221ed9 Mon Sep 17 00:00:00 2001
From: HJfod <60038575+HJfod@users.noreply.github.com>
Date: Wed, 2 Nov 2022 12:47:58 +0200
Subject: [PATCH] preliminary stuff  - customize hardcoded colors api (no impl
 yet)  - more ids

---
 loader/include/Geode/ui/Colors.hpp  | 47 +++++++++++++++
 loader/src/ids/CreatorLayer.cpp     |  6 +-
 loader/src/ids/LevelInfoLayer.cpp   | 91 +++++++++++++++++++++++++++++
 loader/src/ids/LevelSearchLayer.cpp |  2 +-
 loader/src/ui/nodes/Colors.cpp      | 30 ++++++++++
 5 files changed, 173 insertions(+), 3 deletions(-)
 create mode 100644 loader/include/Geode/ui/Colors.hpp
 create mode 100644 loader/src/ids/LevelInfoLayer.cpp
 create mode 100644 loader/src/ui/nodes/Colors.cpp

diff --git a/loader/include/Geode/ui/Colors.hpp b/loader/include/Geode/ui/Colors.hpp
new file mode 100644
index 00000000..fff2215c
--- /dev/null
+++ b/loader/include/Geode/ui/Colors.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "../DefaultInclude.hpp"
+#include "../loader/Mod.hpp"
+#include <cocos2d.h>
+
+namespace geode {
+    // Credit to https://github.com/Ikszyon/UI-Recolor for many of these addresses!
+
+    /**
+     * Hardcoded GD colors
+     */
+    enum class GDColor {
+        NormalModeProgressBar,
+        PracticeModeProgressBar,
+
+        ProfilePostBG,
+    };
+
+    class GEODE_DLL ColorManager {
+    protected:
+        struct Value {
+            cocos2d::ccColor3B value;
+            Mod* setter;
+        };
+
+        std::unordered_map<GDColor, std::vector<Value>> m_colors;
+
+        ColorManager();
+    
+    public:
+        static ColorManager* get();
+
+        cocos2d::ccColor3B getColor(GDColor color) const;
+        void setColor(GDColor color, Mod* setter, cocos2d::ccColor3B const& value);
+        void resetColor(GDColor color, Mod* setter);
+
+        template<class = void>
+        void setColor(GDColor color, cocos2d::ccColor3B const& value) {
+            this->setColor(color, Mod::get(), value);
+        }
+        template<class = void>
+        void resetColor(GDColor color) {
+            this->resetColor(color, Mod::get());
+        }
+    };
+}
diff --git a/loader/src/ids/CreatorLayer.cpp b/loader/src/ids/CreatorLayer.cpp
index 795d54b5..29833d41 100644
--- a/loader/src/ids/CreatorLayer.cpp
+++ b/loader/src/ids/CreatorLayer.cpp
@@ -6,6 +6,8 @@
 USE_GEODE_NAMESPACE();
 
 $register_ids(CreatorLayer) {
+    setIDSafe<CCSprite>(this, 0, "background");
+
     if (auto menu = getChildOfType<CCMenu>(this, 0)) {
         menu->setID("creator-buttons-menu");
 
@@ -37,8 +39,8 @@ $register_ids(CreatorLayer) {
     }
 
     if (auto menu = getChildOfType<CCMenu>(this, 1)) {
-        menu->setID("go-back-menu");
-        setIDSafe(menu, 0, "back-button");
+        menu->setID("exit-menu");
+        setIDSafe(menu, 0, "exit-button");
     }
 }
 
diff --git a/loader/src/ids/LevelInfoLayer.cpp b/loader/src/ids/LevelInfoLayer.cpp
new file mode 100644
index 00000000..af23ae4a
--- /dev/null
+++ b/loader/src/ids/LevelInfoLayer.cpp
@@ -0,0 +1,91 @@
+#include "AddIDs.hpp"
+#include <Geode/modify/LevelInfoLayer.hpp>
+
+$register_ids(LevelInfoLayer) {
+    auto winSize = CCDirector::get()->getWinSize();
+
+    setIDSafe<CCSprite>(this, 0, "background");
+
+    size_t iconOffset = 0;
+
+    setIDSafe<CCSprite>(this, 1, "bottom-left-art");
+    setIDSafe<CCSprite>(this, 2, "bottom-right-art");
+
+    if (m_level->m_highObjectsEnabled) {
+        setIDSafe<CCSprite>(this, 4, "high-object-indicator");
+        iconOffset++;
+    }
+
+    setIDSafe<CCSprite>(this, 4 + iconOffset, "length-icon");
+    setIDSafe<CCSprite>(this, 5 + iconOffset, "downloads-icon");
+    setIDSafe<CCSprite>(this, 6 + iconOffset, "orbs-icon");
+    setIDSafe<CCSprite>(this, 7 + iconOffset, "likes-icon");
+    setIDSafe<CCLabelBMFont>(this, 1, "downloads-label");
+    setIDSafe<CCLabelBMFont>(this, 2, "length-label");
+    setIDSafe<CCLabelBMFont>(this, 3, "likes-label");
+    setIDSafe<CCLabelBMFont>(this, 4, "orbs-label");
+
+    if (m_level->m_stars) {
+        setIDSafe<CCSprite>(this, 8 + iconOffset, "stars-icon");
+        setIDSafe<CCLabelBMFont>(this, 5, "stars-label");
+    }
+
+    setIDSafe<CustomSongWidget>(this, 0, "custom-songs-widget");
+
+    if (auto menu = getChildOfType<CCMenu>(this, 0)) {
+        menu->setID("exit-menu");
+		setIDSafe(menu, 0, "exit-button");
+    }
+
+    if (auto menu = getChildOfType<CCMenu>(this, 1)) {
+        menu->setID("right-side-menu");
+
+        if (auto name = setIDSafe(menu, 0, "creator-name")) {
+            detachIntoOwnMenu(
+                this, name, "creator-info-menu",
+                ColumnLayout::create()->setAlignment(Alignment::Begin)
+            );
+        }
+
+        auto leftSideMenu = CCMenu::create();
+        leftSideMenu->setPosition(winSize / 2 + ccp(-254.f, 30.f));
+        leftSideMenu->setLayout(ColumnLayout::create());
+        leftSideMenu->setID("left-side-menu");
+        this->addChild(leftSideMenu);
+
+        menu->setPosition(winSize / 2 + ccp(254.f, 0.f));
+        
+        for (auto child : CCArrayExt<CCNode>(menu->getChildren())) {
+            if (child->getPositionX() < 0.f) {
+                child->retain();
+                child->removeFromParent();
+                leftSideMenu->addChild(child);
+                child->release();
+            }
+            child->setPositionX(0.f);
+        }
+
+        setIDSafe(menu, 0, "delete-button");
+        setIDSafe(menu, 1, "refresh-button");
+        setIDSafe(menu, 2, "info-button");
+        setIDSafe(menu, 3, "leaderboards-button");
+        setIDSafe(menu, 4, "like-button");
+        setIDSafe(menu, 5, "rate-button");
+
+        setIDSafe(leftSideMenu, 0, "copy-button");
+
+        menu->updateLayout();
+        leftSideMenu->updateLayout();
+    }
+}
+
+class $modify(LevelInfoLayer) {
+    bool init(GJGameLevel* level) {
+        if (!LevelInfoLayer::init(level))
+            return false;
+        
+        NodeStringIDManager::get()->provide(this);
+
+        return true;
+    }
+};
diff --git a/loader/src/ids/LevelSearchLayer.cpp b/loader/src/ids/LevelSearchLayer.cpp
index 99301b29..504e1ab8 100644
--- a/loader/src/ids/LevelSearchLayer.cpp
+++ b/loader/src/ids/LevelSearchLayer.cpp
@@ -3,7 +3,7 @@
 
 $register_ids(LevelSearchLayer) {
 	// set the funny ids
-	setIDSafe(this, 0, "creator-layer-bg");
+	setIDSafe(this, 0, "background");
 	getChildOfType<CCTextInputNode>(this, 0)->setID("search-bar");
 	getChildOfType<CCScale9Sprite>(this, 0)->setID("level-search-bg");
 	getChildOfType<CCScale9Sprite>(this, 1)->setID("level-search-bar-bg");
diff --git a/loader/src/ui/nodes/Colors.cpp b/loader/src/ui/nodes/Colors.cpp
new file mode 100644
index 00000000..133ca19d
--- /dev/null
+++ b/loader/src/ui/nodes/Colors.cpp
@@ -0,0 +1,30 @@
+#include <Geode/ui/Colors.hpp>
+#include <Geode/utils/ranges.hpp>
+#include <Geode/modify/LevelInfoLayer.hpp>
+
+USE_GEODE_NAMESPACE();
+
+ColorManager::ColorManager() : m_colors({
+    { GDColor::NormalModeProgressBar,   {{ ccColor3B { 0,   255, 0   }, Mod::get() }} },
+    { GDColor::PracticeModeProgressBar, {{ ccColor3B { 0,   255, 255 }, Mod::get() }} },
+    { GDColor::ProfilePostBG,           {{ ccColor3B { 191, 114, 62  }, Mod::get() }} },
+}) {}
+
+ColorManager* ColorManager::get() {
+    static auto inst = new ColorManager;
+    return inst;
+}
+
+ccColor3B ColorManager::getColor(GDColor color) const {
+    return m_colors.at(color).back().value;
+}
+
+void ColorManager::setColor(GDColor color, Mod* setter, ccColor3B const& value) {
+    m_colors.at(color).push_back({ value, setter });
+}
+
+void ColorManager::resetColor(GDColor color, Mod* setter) {
+    ranges::remove(m_colors.at(color), [setter](Value const& value) {
+        return value.setter == setter;
+    });
+}