From 6b96391f28e66f920054764f89c4a23f261bb1f0 Mon Sep 17 00:00:00 2001
From: Alphalaneous <38200084+Alphalaneous@users.noreply.github.com>
Date: Thu, 16 May 2024 07:25:18 -0400
Subject: [PATCH] Code organization
---
README.md | 130 ++++++++++++++++++++++
src/UIModding.cpp | 275 ++++++++++++++++++++++------------------------
src/UIModding.h | 57 ++++++++++
3 files changed, 318 insertions(+), 144 deletions(-)
create mode 100644 src/UIModding.h
diff --git a/README.md b/README.md
index 1d0de35..ed6aae2 100644
--- a/README.md
+++ b/README.md
@@ -363,6 +363,136 @@ When it comes to using the position attribute, you can change the x and y coordi
+ |
+
+
+
+ text |
+ Set the text of a label or button. |
+
+
+```json
+"text": "example"
+```
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+ scale-multiplier |
+ Set the scale multiplier for when you click on a button. |
+
+
+```json
+"scale-multiplier": 1.4
+```
+
+ |
+
+
+
+
+ |
+
+
+
+ z-order |
+ Set the z order of a node. |
+
+
+```json
+"z-order": 2
+```
+
+ |
+
+
+
+
+ |
+
+
+
+ font |
+ Set the bitmap font of a label or button. |
+
+
+```json
+"font": "chatFont.fnt"
+```
+
+ |
+
+
+
+
+ |
+
+
+
+ blending |
+ Set the blending of a node, see OpenGL documentation for how to use blending modes. |
+
+
+```json
+"blending": {
+ "source": "GL_ONE_MINUS_SRC_COLOR",
+ "destination": "GL_ONE_MINUS_SRC_ALPHA"
+}
+```
+
+ |
+
+
+
+
+ |
+
+
+
+ sound |
+ Set a sound to play on node attribute change. Useful for onHover and onClick events. |
+
+
+```json
+"sound": "effect.ogg"
+```
+
+ |
+
+
+
+
+ |
+
+
+
+ link |
+ Set a link to open on node attribute change. Useful for onClick events. Can be a URL or link to a "profile" or "level" with the type attribute. |
+
+
+```json
+"link": "https://google.com"
+```
+
+ |
+
+
+
+```json
+"link": {
+ "type": "profile",
+ "id": 123456,
+}
+```
+
|
diff --git a/src/UIModding.cpp b/src/UIModding.cpp
index 8a448b6..7849b37 100644
--- a/src/UIModding.cpp
+++ b/src/UIModding.cpp
@@ -2,43 +2,14 @@
#include
#include
#include
+#include
#include "FileWatcher.h"
#include "Utils.h"
#include "CCLabelBMFont.h"
-#include
+#include "UIModding.h"
using namespace geode::prelude;
-void recursiveModify(CCNode* node, matjson::Object elements);
-void setVisible(CCNode* node, matjson::Object attributes);
-void setIgnoreAnchorPos(CCNode* node, matjson::Object attributes);
-void setScale(CCNode* node, matjson::Object attributes);
-void setRotation(CCNode* node, matjson::Object attributes);
-void setSkew(CCNode* node, matjson::Object attributes);
-void setAnchorPoint(CCNode* node, matjson::Object attributes);
-void setContentSize(CCNode* node, matjson::Object attributes);
-void setPosition(CCNode* node, matjson::Object attributes);
-void setColor(CCNode* node, matjson::Object attributes);
-void setText(CCNode* node, matjson::Object attributes);
-void setScaleMult(CCNode* node, matjson::Object attributes);
-void setZOrder(CCNode* node, matjson::Object attributes);
-void setFont(CCNode* node, matjson::Object attributes);
-void setBlending(CCNode* node, matjson::Object attributes);
-void playSound(CCNode* node, matjson::Object attributes);
-void openLink(CCNode* node, matjson::Object attributes);
-void setLayout(CCNode* node, matjson::Object attributes);
-void updateLayout(CCNode* node, matjson::Object attributes);
-void runAction(CCNode* node, matjson::Object attributes);
-CCActionInterval* createAction(matjson::Value action);
-CCActionInterval* getEasingType(std::string name, CCActionInterval* action, float rate);
-unsigned int stringToBlendingMode(std::string value);
-void handleModifications(CCNode* node, matjson::Object nodeObject);
-void doUICheck(CCNode* node);
-std::vector getActivePacks();
-bool endsWith(std::string value, std::string ending);
-bool startsWith(std::string value, std::string start);
-void startFileListeners();
-
class $modify(MenuLayer){
bool init(){
startFileListeners();
@@ -315,60 +286,26 @@ CCActionInterval* getEasingType(std::string name, CCActionInterval* action, floa
if(name == "none"){
easingType = action;
}
- else if(name == "EaseInOut"){
- easingType = CCEaseInOut::create(action, rate);
- }
- else if(name == "EaseIn"){
- easingType = CCEaseIn::create(action, rate);
- }
- else if(name == "EaseOut"){
- easingType = CCEaseOut::create(action, rate);
- }
- else if(name == "ElasticInOut"){
- easingType = CCEaseElasticInOut::create(action, rate);
- }
- else if(name == "ElasticIn"){
- easingType = CCEaseElasticIn::create(action, rate);
- }
- else if(name == "ElasticOut"){
- easingType = CCEaseElasticOut::create(action, rate);
- }
- else if(name == "BounceInOut"){
- easingType = CCEaseBounceInOut::create(action);
- }
- else if(name == "BounceIn"){
- easingType = CCEaseBounceIn::create(action);
- }
- else if(name == "BounceOut"){
- easingType = CCEaseBounceOut::create(action);
- }
- else if(name == "ExponentialInOut"){
- easingType = CCEaseExponentialInOut::create(action);
- }
- else if(name == "ExponentialOut"){
- easingType = CCEaseExponentialOut::create(action);
- }
- else if(name == "ExponentialIn"){
- easingType = CCEaseExponentialIn::create(action);
- }
- else if(name == "SineInOut"){
- easingType = CCEaseSineInOut::create(action);
- }
- else if(name == "SineOut"){
- easingType = CCEaseSineOut::create(action);
- }
- else if(name == "SineIn"){
- easingType = CCEaseSineIn::create(action);
- }
- else if(name == "BackInOut"){
- easingType = CCEaseBackInOut::create(action);
- }
- else if(name == "BackOut"){
- easingType = CCEaseBackOut::create(action);
- }
- else if(name == "BackIn"){
- easingType = CCEaseBackIn::create(action);
- }
+
+ typeForEaseCC(EaseInOut);
+ typeForEaseCC(EaseIn);
+ typeForEaseCC(EaseOut);
+ typeForEaseRate(ElasticInOut);
+ typeForEaseRate(ElasticIn);
+ typeForEaseRate(ElasticOut);
+ typeForEase(BounceInOut);
+ typeForEase(BounceIn);
+ typeForEase(BounceOut);
+ typeForEase(ExponentialInOut);
+ typeForEase(ExponentialIn);
+ typeForEase(ExponentialOut);
+ typeForEase(SineInOut);
+ typeForEase(SineIn);
+ typeForEase(SineOut);
+ typeForEase(BackInOut);
+ typeForEase(BackIn);
+ typeForEase(BackOut);
+
return easingType;
}
@@ -1058,47 +995,111 @@ void handleModifications(CCNode* node, matjson::Object nodeObject){
if(nodeAttributes.is_object()){
matjson::Object nodeAttributesObject = nodeAttributes.as_object();
- setScale(node, nodeAttributesObject);
- setRotation(node, nodeAttributesObject);
- setSkew(node, nodeAttributesObject);
- setAnchorPoint(node, nodeAttributesObject);
- setContentSize(node, nodeAttributesObject);
- setVisible(node, nodeAttributesObject);
- setIgnoreAnchorPos(node, nodeAttributesObject);
- setColor(node, nodeAttributesObject);
- setOpacity(node, nodeAttributesObject);
- setSprite(node, nodeAttributesObject);
- setSpriteFrame(node, nodeAttributesObject);
- setPosition(node, nodeAttributesObject);
- setText(node, nodeAttributesObject);
- setScaleMult(node, nodeAttributesObject);
- setZOrder(node, nodeAttributesObject);
- setFont(node, nodeAttributesObject);
- setBlending(node, nodeAttributesObject);
- setLayout(node, nodeAttributesObject);
- updateLayout(node, nodeAttributesObject);
- runAction(node, nodeAttributesObject);
- playSound(node, nodeAttributesObject);
- openLink(node, nodeAttributesObject);
+ nodesFor(Scale);
+ nodesFor(Rotation);
+ nodesFor(Skew);
+ nodesFor(AnchorPoint);
+ nodesFor(ContentSize);
+ nodesFor(Visible);
+ nodesFor(IgnoreAnchorPos);
+ nodesFor(Color);
+ nodesFor(Opacity);
+ nodesFor(Sprite);
+ nodesFor(SpriteFrame);
+ nodesFor(Position);
+ nodesFor(Text);
+ nodesFor(ScaleMult);
+ nodesFor(ZOrder);
+ nodesFor(Font);
+ nodesFor(Blending);
+ nodesFor(Layout);
+ nodesForMethod(updateLayout);
+ nodesForMethod(runAction);
+ nodesForMethod(playSound);
+ nodesForMethod(openLink);
}
}
if(nodeObject.contains("children")){
- matjson::Value nodeChildren = nodeObject["children"];
- if(nodeChildren.is_object()){
- matjson::Object nodeChildrenObject = nodeChildren.as_object();
- recursiveModify(node, nodeChildrenObject);
- }
- }
-
- if(nodeObject.contains("all-children")){
+ matjson::Value childrenVal = nodeObject["children"];
+ if(childrenVal.is_object()){
+ matjson::Object childrenObject = childrenVal.as_object();
+
+ if(childrenVal.contains("node")){
+ matjson::Value nodeChildrenVal = childrenObject["node"];
+ if(nodeChildrenVal.is_object()){
+ matjson::Object nodeChildrenObject = nodeChildrenVal.as_object();
+ recursiveModify(node, nodeChildrenObject);
+ }
+ }
+ if(childrenVal.contains("index")){
+ matjson::Value indexChildrenVal = childrenObject["index"];
+ if(indexChildrenVal.is_array()){
+ matjson::Array nodeChildrenArray = indexChildrenVal.as_array();
+
+ for(matjson::Value value : nodeChildrenArray){
+ if(value.is_object()){
+ matjson::Object childObject = value.as_object();
+
+ int index = 0;
+ std::string type = "CCNode";
+ if(value.contains("index")){
+ matjson::Value indexVal = value["index"];
+ if(indexVal.is_number()){
+ index = indexVal.as_int();
+ }
+ }
+ if(value.contains("type")){
+ matjson::Value typeVal = value["type"];
+ if(typeVal.is_string()){
+ type = typeVal.as_string();
+ }
+ }
+
+ modifyForType(CCSprite);
+ modifyForType(CCMenu);
+ modifyForType(CCMenuItemSpriteExtra);
+ modifyForType(CCLabelBMFont);
+ modifyForType(CCLayer);
+ modifyForType(CCScale9Sprite);
+ modifyForType(CCSpriteBatchNode);
+ modifyForType(CCTextInputNode);
+ modifyForType(CCTextFieldTTF);
+ modifyForType(TextArea);
+ modifyForType(MultilineBitmapFont);
+ modifyForType(Slider);
+ modifyForType(ButtonSprite);
+ modifyForType(CircleButtonSprite);
+ modifyForType(SearchButton);
+ modifyForType(LoadingCircle);
+ modifyForType(BoomScrollLayer);
+ modifyForType(ListButtonBar);
+ modifyForType(ExtendedLayer);
+ modifyForType(SimplePlayer);
+ modifyForType(DailyLevelNode);
+ modifyForType(GJListLayer);
+ modifyForType(CustomListView);
+ modifyForType(TableView);
+ modifyForType(CCContentLayer);
+ modifyForType(CCLayerColor);
+ modifyForType(LevelCell);
+ modifyForType(CustomSongWidget);
+ modifyForType(GJDifficultySprite);
+ modifyForType(GJCommentListLayer);
- matjson::Value nodeAllChildren = nodeObject["all-children"];
- if(nodeAllChildren.is_object()){
- matjson::Object nodeAllChildrenObject = nodeAllChildren.as_object();
- for(CCNode* node : CCArrayExt(node->getChildren())){
- handleModifications(node, nodeAllChildrenObject);
- }
+ }
+ }
+ }
+ }
+ if(childrenVal.contains("all")){
+ matjson::Value allChildrenVal = childrenObject["all"];
+ if(allChildrenVal.is_object()){
+ matjson::Object allChildrenObject = allChildrenVal.as_object();
+ for(CCNode* node : CCArrayExt(node->getChildren())){
+ handleModifications(node, allChildrenObject);
+ }
+ }
+ }
}
}
}
@@ -1113,15 +1114,12 @@ void doUICheck(CCNode* node){
if (buffer && fileSize != 0) {
std::string data = std::string(reinterpret_cast(buffer), fileSize);
-
std::string error;
-
std::optional value = matjson::parse(data, error);
if(value.has_value()){
matjson::Value expandedValue = value.value();
-
if(!expandedValue.is_null()){
matjson::Object object = expandedValue.as_object();
handleModifications(node, object);
@@ -1134,15 +1132,11 @@ void doUICheck(CCNode* node){
std::vector listeners;
void startFileListeners(){
-
for(FileWatcher* fw : listeners){
fw->stop();
}
-
listeners.clear();
-
std::vector packs = getActivePacks();
-
for(std::string path : packs){
std::string uiPath = fmt::format("{}{}", path, "ui\\");
@@ -1169,13 +1163,9 @@ void startFileListeners(){
std::vector getActivePacks(){
gd::vector paths = CCFileUtils::sharedFileUtils()->getSearchPaths();
-
std::vector packPaths;
-
Mod* textureLoader = Loader::get()->getLoadedMod("geode.texture-loader");
-
ghc::filesystem::path textureLoaderPacks = textureLoader->getConfigDir();
-
std::string packDirStr = fmt::format("{}{}", textureLoaderPacks, "\\packs");
ghc::filesystem::path packDir = ghc::filesystem::path(packDirStr);
@@ -1196,25 +1186,22 @@ std::vector getActivePacks(){
return packPaths;
}
-bool endsWith(std::string value, std::string ending){
+void toLower(std::string value){
for(auto& c : value){
c = tolower(c);
}
- for(auto& c : ending){
- c = tolower(c);
- }
+}
+
+bool endsWith(std::string value, std::string ending){
+ toLower(value);
+ toLower(ending);
return value.ends_with(ending);
}
bool startsWith(std::string value, std::string start){
- for(auto& c : value){
- c = tolower(c);
- }
- for(auto& c : start){
- c = tolower(c);
- }
+ toLower(value);
+ toLower(start);
return value.starts_with(start);
-}
-
+}
\ No newline at end of file
diff --git a/src/UIModding.h b/src/UIModding.h
new file mode 100644
index 0000000..03f0886
--- /dev/null
+++ b/src/UIModding.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include
+
+void recursiveModify(CCNode* node, matjson::Object elements);
+void setVisible(CCNode* node, matjson::Object attributes);
+void setIgnoreAnchorPos(CCNode* node, matjson::Object attributes);
+void setScale(CCNode* node, matjson::Object attributes);
+void setRotation(CCNode* node, matjson::Object attributes);
+void setSkew(CCNode* node, matjson::Object attributes);
+void setAnchorPoint(CCNode* node, matjson::Object attributes);
+void setContentSize(CCNode* node, matjson::Object attributes);
+void setPosition(CCNode* node, matjson::Object attributes);
+void setColor(CCNode* node, matjson::Object attributes);
+void setText(CCNode* node, matjson::Object attributes);
+void setScaleMult(CCNode* node, matjson::Object attributes);
+void setZOrder(CCNode* node, matjson::Object attributes);
+void setFont(CCNode* node, matjson::Object attributes);
+void setBlending(CCNode* node, matjson::Object attributes);
+void playSound(CCNode* node, matjson::Object attributes);
+void openLink(CCNode* node, matjson::Object attributes);
+void setLayout(CCNode* node, matjson::Object attributes);
+void updateLayout(CCNode* node, matjson::Object attributes);
+void runAction(CCNode* node, matjson::Object attributes);
+CCActionInterval* createAction(matjson::Value action);
+CCActionInterval* getEasingType(std::string name, CCActionInterval* action, float rate);
+unsigned int stringToBlendingMode(std::string value);
+void handleModifications(CCNode* node, matjson::Object nodeObject);
+void doUICheck(CCNode* node);
+std::vector getActivePacks();
+bool endsWith(std::string value, std::string ending);
+bool startsWith(std::string value, std::string start);
+void startFileListeners();
+
+#define typeForEaseCC(easingTypeName) \
+if(name == #easingTypeName){\
+ easingType = CC##easingTypeName::create(action, rate);\
+}
+
+#define typeForEaseRate(easingTypeName) \
+if(name == #easingTypeName){\
+ easingType = CCEase##easingTypeName::create(action, rate);\
+}
+
+#define typeForEase(easingTypeName) \
+if(name == #easingTypeName){\
+ easingType = CCEase##easingTypeName::create(action);\
+}
+
+#define modifyForType(typeName) \
+if(type == #typeName){\
+ handleModifications(getChildOfType(node, index), childObject);\
+}
+
+#define nodesFor(methodName) set##methodName(node, nodeAttributesObject)
+
+#define nodesForMethod(methodName) methodName(node, nodeAttributesObject)