revenge-tweak/Sources/Theme.m
2024-11-15 11:45:12 +01:00

82 lines
2.8 KiB
Objective-C

#import "Theme.h"
#import "Utils.h"
#import "Logger.h"
#import <objc/runtime.h>
void swizzleDCDThemeColor(NSDictionary<NSString *, NSArray<NSString *> *> *semanticColors) {
RevengeLog(@"Swizzling DCDThemeColor");
Class DCDTheme = NSClassFromString(@"DCDTheme");
Class dcdThemeTarget = object_getClass(DCDTheme);
SEL themeIndexSelector = NSSelectorFromString(@"themeIndex");
Method themeIndexMethod = class_getClassMethod(dcdThemeTarget, themeIndexSelector);
IMP themeIndexImpl = method_getImplementation(themeIndexMethod);
int (*themeIndex)(id, SEL) = (int (*)(id, SEL))themeIndexImpl;
Class DCDThemeColor = NSClassFromString(@"DCDThemeColor");
Class target = object_getClass(DCDThemeColor);
unsigned int methodCount;
Method *methods = class_copyMethodList(target, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
SEL selector = method_getName(method);
NSString *methodName = NSStringFromSelector(selector);
NSArray<NSString *> *semanticColor = semanticColors[methodName];
if (semanticColor) {
RevengeLog(@"Swizzling %@", methodName);
IMP originalImpl = method_getImplementation(method);
UIColor *(*original)(id, SEL) = (UIColor *(*)(id, SEL))originalImpl;
id block = ^UIColor *(id self) {
int themeIndexVal = themeIndex(dcdThemeTarget, themeIndexSelector);
if (semanticColor.count - 1 >= themeIndexVal) {
UIColor *semanticUIColor = hexToUIColor(semanticColor[themeIndexVal]);
if (semanticUIColor) {
return semanticUIColor;
}
}
return original(target, selector);
};
IMP newImpl = imp_implementationWithBlock(block);
method_setImplementation(method, newImpl);
}
}
free(methods);
}
void swizzleUIColor(NSDictionary<NSString *, NSString *> *rawColors) {
RevengeLog(@"Swizzling UIColor");
Class UIColorClass = NSClassFromString(@"UIColor");
Class target = object_getClass(UIColorClass);
unsigned int methodCount;
Method *methods = class_copyMethodList(target, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
SEL selector = method_getName(method);
NSString *methodName = NSStringFromSelector(selector);
NSString *rawColor = rawColors[methodName];
if (rawColor) {
RevengeLog(@"Swizzling %@", methodName);
id block = ^UIColor *(id self) {
return hexToUIColor(rawColor);
};
IMP newImpl = imp_implementationWithBlock(block);
method_setImplementation(method, newImpl);
}
}
free(methods);
}