From b10a3285bfcb63e4a0fc72963ad5acda2c245f37 Mon Sep 17 00:00:00 2001 From: pixelomer <37103802+pixelomer@users.noreply.github.com> Date: Sat, 8 Feb 2020 00:28:31 +0300 Subject: [PATCH] Initial commit --- .gitattributes | 2 + .gitignore | 3 + Goose/MGGooseView.h | 7 +++ Goose/MGGooseView.mm | 132 +++++++++++++++++++++++++++++++++++++++++++ Makefile | 10 ++++ MobileGoose.plist | 1 + README.md | 2 + Tweak.xm | 27 +++++++++ control | 9 +++ 9 files changed, 193 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Goose/MGGooseView.h create mode 100644 Goose/MGGooseView.mm create mode 100644 Makefile create mode 100644 MobileGoose.plist create mode 100644 README.md create mode 100644 Tweak.xm create mode 100644 control diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62ac258 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +packages +.theos +obj \ No newline at end of file diff --git a/Goose/MGGooseView.h b/Goose/MGGooseView.h new file mode 100644 index 0000000..b44c12c --- /dev/null +++ b/Goose/MGGooseView.h @@ -0,0 +1,7 @@ +#import + +@interface MGGooseView : UIView { + NSTimer *timer; +} +@property (nonatomic, assign) CGFloat facingTo; +@end \ No newline at end of file diff --git a/Goose/MGGooseView.mm b/Goose/MGGooseView.mm new file mode 100644 index 0000000..56cb4c3 --- /dev/null +++ b/Goose/MGGooseView.mm @@ -0,0 +1,132 @@ +#import "MGGooseView.h" + +#define DEG_TO_RAD(degress) ((degress) * M_PI / 180.0) + +@implementation MGGooseView + ++ (void)rotatePath:(UIBezierPath *)path degree:(CGFloat)degree { + CGRect bounds = CGPathGetBoundingBox(path.CGPath); + CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); + + CGFloat radians = (degree / 180.0f * M_PI); + CGAffineTransform transform = CGAffineTransformIdentity; + transform = CGAffineTransformTranslate(transform, center.x, center.y); + transform = CGAffineTransformRotate(transform, radians); + transform = CGAffineTransformTranslate(transform, -center.x, -center.y); + [path applyTransform:transform]; +} + +- (CGSize)sizeThatFits:(CGSize)size { + return CGSizeMake(80, 80); +} + +- (void)drawRect:(CGRect)rect { + CGFloat facingToRadians = _facingTo * M_PI / 180.0; + CGFloat facingToDegrees = _facingTo; + + // Shadow + [[UIColor colorWithWhite:0.25 alpha:0.25] setFill]; + @autoreleasepool { + UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 30, 30, 30)]; + [path fill]; + } + + // Feet + [[UIColor orangeColor] setFill]; + @autoreleasepool { + UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 45, 8, 8)]; + [path fill]; + } + + // Body + [[UIColor whiteColor] setFill]; + @autoreleasepool { + CGRect oval1Rect = CGRectMake(15, 20, 20, 20); + UIBezierPath *oval1 = [UIBezierPath bezierPathWithOvalInRect:oval1Rect]; + CGRect oval2Rect = CGRectMake(oval1Rect.origin.x, 55-oval1Rect.size.height, oval1Rect.size.width, oval1Rect.size.height); + UIBezierPath *oval2 = [UIBezierPath bezierPathWithOvalInRect:oval2Rect]; + CGRect rectangleRect = CGRectMake(oval1Rect.origin.x, oval1Rect.origin.y+oval1Rect.size.height/2, oval1Rect.size.width, oval2Rect.origin.y-oval1Rect.origin.y); + UIBezierPath *finalPath = [UIBezierPath bezierPathWithRect:rectangleRect]; + [finalPath appendPath:oval1]; + [finalPath appendPath:oval2]; + [self.class rotatePath:finalPath degree:facingToDegrees+90.0]; + [finalPath fill]; + } + + // Neck + @autoreleasepool { + // Create a rect without the correct position + const CGFloat neckHeight = 10; + CGRect rect = CGRectMake(0, 20, 15, neckHeight); + + // Calculate the correct position + const CGFloat radius = 10.0; + rect.origin.x += 17.5 + (radius * cos(facingToRadians)); + rect.origin.y += 4.8 + (radius * sin(facingToRadians)); + + // Draw the neck + UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect]; + rect = CGRectMake( + rect.origin.x, + rect.origin.y + rect.size.width - (rect.size.width / 2), + rect.size.width, + rect.size.width + ); + [path appendPath:[UIBezierPath bezierPathWithOvalInRect:rect]]; + rect.origin.y -= rect.size.width; + [path appendPath:[UIBezierPath bezierPathWithOvalInRect:rect]]; + [path fill]; + } + + // Face + @autoreleasepool { + // Create a rect without the correct position + const CGFloat beakSize = 8.0; + CGRect rect = CGRectMake(0, 20, beakSize, beakSize); + + // Calculate the correct position + const CGFloat beakRadius = 15.0; + rect.origin.x += 21.0 + (beakRadius * cos(facingToRadians)); + rect.origin.y += 4.5 + (beakRadius * sin(facingToRadians)); + + [[UIColor orangeColor] setFill]; + UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect]; + [path fill]; + + const CGFloat eyeSize = beakSize * 0.6; + const CGFloat eyeRadius = beakRadius - 3.0; + rect.size.height = rect.size.width = eyeSize; + [[UIColor blackColor] setFill]; + for (int8_t i=0, offset=15; i<2; i+=1.0) { + rect.origin.x = 22.5 + (eyeRadius * cos(DEG_TO_RAD(facingToDegrees + offset))); + rect.origin.y = 24.5 + (eyeRadius * sin(DEG_TO_RAD(facingToDegrees + offset))); + path = [UIBezierPath bezierPathWithOvalInRect:rect]; + [path fill]; + offset = -offset; + } + } +} + +- (void)timer:(id)unused { + self.facingTo += 1.0; + if (self.facingTo >= 360.0) { + self.facingTo = 0.0; + } + if (!((int)self.facingTo % 30)) { + CGRect rect = self.frame; + rect.origin.x++; + self.frame = rect; + } + [self setNeedsDisplay]; +} + +- (instancetype)init { + if ((self = [super init])) { + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/30.0) target:self selector:@selector(timer:) userInfo:nil repeats:YES]; + } + return self; +} + +@end diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7ab81b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +INSTALL_TARGET_PROCESSES = SpringBoard + +include $(THEOS)/makefiles/common.mk + +TWEAK_NAME = MobileGoose + +MobileGoose_FILES = Tweak.xm $(wildcard */*.mm) +MobileGoose_CFLAGS = -fobjc-arc -I. + +include $(THEOS_MAKE_PATH)/tweak.mk diff --git a/MobileGoose.plist b/MobileGoose.plist new file mode 100644 index 0000000..10dc654 --- /dev/null +++ b/MobileGoose.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.springboard" ); }; } diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4b47fb --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# mobilegoose + Desktop Goose except it's worse and it's for iOS diff --git a/Tweak.xm b/Tweak.xm new file mode 100644 index 0000000..5f29408 --- /dev/null +++ b/Tweak.xm @@ -0,0 +1,27 @@ +#import +#import + +static UIWindow *gooseWindow; + +%hook SpringBoard + +- (void)applicationDidFinishLaunching:(id)application { + %orig; + gooseWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + gooseWindow.screen = [UIScreen mainScreen]; + gooseWindow.userInteractionEnabled = NO; + gooseWindow.opaque = NO; + gooseWindow.hidden = NO; + gooseWindow.backgroundColor = [UIColor clearColor]; + gooseWindow.rootViewController = [UIViewController new]; + MGGooseView *gooseView = [MGGooseView new]; + CGRect frame = CGRectMake(100, 100, 0, 0); + frame.size = [gooseView sizeThatFits:frame.size]; + gooseView.frame = frame; + [gooseWindow.rootViewController.view addSubview:gooseView]; + gooseWindow.windowLevel = CGFLOAT_MAX - 1; + [gooseWindow makeKeyAndVisible]; + [gooseWindow resignKeyWindow]; +} + +%end \ No newline at end of file diff --git a/control b/control new file mode 100644 index 0000000..df5e586 --- /dev/null +++ b/control @@ -0,0 +1,9 @@ +Package: com.pixelomer.mobilegoose +Name: MobileGoose +Depends: mobilesubstrate +Version: 0.0.1 +Architecture: iphoneos-arm +Description: An awesome MobileSubstrate tweak! +Maintainer: PixelOmer +Author: PixelOmer +Section: Tweaks