Skip to content

Commit

Permalink
More comments, optimization, preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelomer committed Feb 15, 2020
1 parent 224a06a commit be42073
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 32 deletions.
13 changes: 9 additions & 4 deletions Goose/MGGooseView.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#import <UIKit/UIKit.h>

// ALL of the methods in this class MUST be called on the main thread.

@class MGGooseView;

typedef NS_ENUM(NSInteger, MGGooseFrameState) {
Expand All @@ -15,6 +17,7 @@ typedef NS_ENUM(NSInteger, MGGooseFrameState) {
#undef e
};
typedef void(^MGGooseFrameHandler)(MGGooseView *, MGGooseFrameState);
typedef void(^MGGooseCommonBlock)(MGGooseView *);

// Do you think I'm using the wrong terms in variable names? If so,
// feel free to make a pull request that fixes it.
Expand All @@ -26,20 +29,22 @@ typedef void(^MGGooseFrameHandler)(MGGooseView *, MGGooseFrameState);
NSInteger _walkingState;
CGFloat _targetFacingTo;
NSInteger _remainingFramesUntilCompletion;
void(^_walkCompletion)(MGGooseView *);
void(^_animationCompletion)(MGGooseView *);
MGGooseCommonBlock _walkCompletion;
MGGooseCommonBlock _animationCompletion;
CGFloat _walkMultiplier;
NSPointerArray *_frameHandlers;
}
@property (nonatomic, strong) BOOL(^shouldRenderFrameBlock)(MGGooseView *);
@property (nonatomic, assign) CGFloat facingTo;
@property (nonatomic, assign) BOOL stopsAtEdge;
@property (nonatomic, assign, readonly) CGPoint positionChange;
@property (nonatomic, assign) BOOL autoResetFeet;
- (void)walkForDuration:(NSTimeInterval)duration
speed:(CGFloat)speed
completionHandler:(void(^)(MGGooseView *))completion;
completionHandler:(MGGooseCommonBlock)completion;
- (void)setFacingTo:(CGFloat)degress
animationCompletion:(void(^)(MGGooseView *))completion;
animationCompletion:(MGGooseCommonBlock)completion;
- (NSUInteger)addFrameHandler:(MGGooseFrameHandler)handler;
- (void)removeFrameHandlerAtIndex:(NSUInteger)index;
- (BOOL)isFrameAtEdge:(CGRect)frame;
@end
32 changes: 25 additions & 7 deletions Goose/MGGooseView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,14 @@ - (void)advanceDrawingState:(int *)state {
}

- (void)drawRect:(CGRect)rect {
// If shouldRenderFrameBlock() returns NO, don't drawRect
if (_shouldRenderFrameBlock && !_shouldRenderFrameBlock(self)) return;

// Initialize state stuff for mods
int state = 0;
[self notifyFrameHandlers:MGGooseWillStartDrawing];

// Radians, degrees, etc.
CGFloat facingToDegrees = (_facingTo + -[[self._viewControllerForAncestor valueForKey:@"lastDegrees"] doubleValue]);
CGFloat facingToRadians = facingToDegrees * M_PI / 180.0;

Expand Down Expand Up @@ -228,19 +233,24 @@ - (void)removeFrameHandlerAtIndex:(NSUInteger)index {
[_frameHandlers replacePointerAtIndex:index withPointer:NULL];
}

- (void)setFacingTo:(CGFloat)degrees animationCompletion:(void(^)(MGGooseView *))completion {
- (void)setFacingTo:(CGFloat)degrees animationCompletion:(MGGooseCommonBlock)completion {
_targetFacingTo = degrees;
_targetFacingTo -= floor(_targetFacingTo / 360.0) * 360.0;
_animationCompletion = completion;
}

- (void)walkForDuration:(NSTimeInterval)duration speed:(CGFloat)multiplier completionHandler:(void(^)(MGGooseView *))completion {
- (void)walkForDuration:(NSTimeInterval)duration speed:(CGFloat)multiplier completionHandler:(MGGooseCommonBlock)completion {
_remainingFramesUntilCompletion = duration * FPS;
_walkCompletion = completion;
_walkingState = (multiplier >= 0.0) ? 3 : 2;
_walkMultiplier = multiplier;
}

- (void)timer:(id)unused {
// If shouldRenderFrameBlock() returns NO, don't drawRect
if (_shouldRenderFrameBlock && !_shouldRenderFrameBlock(self)) return;

// If _targetFacingTo is positive, continue the turning animation
if (_targetFacingTo >= 0.0) {
CGFloat change;
if (_targetFacingTo > _facingTo) change = 1.0;
Expand All @@ -251,7 +261,7 @@ - (void)timer:(id)unused {
_targetFacingTo = -1.0;
if (_animationCompletion) {
// Completion handler might set _animationCompletion itself.
void(^completion)(MGGooseView *) = _animationCompletion;
MGGooseCommonBlock completion = _animationCompletion;
_animationCompletion = nil;
completion(self);
}
Expand All @@ -263,6 +273,8 @@ - (void)timer:(id)unused {
_facingTo += change;
}
}

// If _remainingFramesUntilCompletion is not -1, continue walking
CGRect oldFrame = self.frame;
if (_remainingFramesUntilCompletion != -1) {
CGRect frame = self.frame;
Expand All @@ -285,16 +297,22 @@ - (void)timer:(id)unused {
self.frame = frame;
}
}

// If the goose finished walking, call the completion handler
if ((_remainingFramesUntilCompletion == -1) && _walkCompletion) {
void(^completion)(MGGooseView *) = _walkCompletion;
MGGooseCommonBlock completion = _walkCompletion;
_walkCompletion = nil;
completion(self);
}
if (_facingTo >= 360.0) {
_facingTo = 0.0;
}

// _facingTo has to be in the (0 ... 360) range
_facingTo -= floor(_facingTo / 360.0) * 360.0;

// Set the position change variable
_positionChange.x = self.frame.origin.x - oldFrame.origin.x;
_positionChange.y = self.frame.origin.y - oldFrame.origin.y;

// Set the "needs display" flag so that drawRect: is called
[self setNeedsDisplay];
}

Expand Down
2 changes: 1 addition & 1 deletion Goose/MGTextContainerView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ - (instancetype)initWithFrame:(CGRect)frame {
if (!_textLabel) return nil;
_textLabel.textColor = [UIColor colorWithWhite:0.0 alpha:0.5];
_textLabel.numberOfLines = 0;
_textLabel.font = [UIFont systemFontOfSize:20.0];
_textLabel.adjustsFontSizeToFitWidth = YES;
_textLabel.textAlignment = NSTextAlignmentCenter;
_textLabel.minimumScaleFactor = 0.1;
[self.contentView addSubview:_textLabel];
}
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
INSTALL_TARGET_PROCESSES = SpringBoard
TARGET = iphone:11.2:8.0
export TARGET

include $(THEOS)/makefiles/common.mk

Expand All @@ -9,3 +11,5 @@ MobileGoose_FILES = Tweak.xm $(wildcard */*.mm)
MobileGoose_CFLAGS = -fobjc-arc -I. -include macros.h

include $(THEOS_MAKE_PATH)/tweak.mk
SUBPROJECTS += Prefs
include $(THEOS_MAKE_PATH)/aggregate.mk
15 changes: 15 additions & 0 deletions Prefs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
include $(THEOS)/makefiles/common.mk

BUNDLE_NAME = MobileGoose

MobileGoose_FILES = PXMGPRootListController.m
MobileGoose_INSTALL_PATH = /Library/PreferenceBundles
MobileGoose_FRAMEWORKS = UIKit
MobileGoose_PRIVATE_FRAMEWORKS = Preferences
MobileGoose_CFLAGS = -fobjc-arc

include $(THEOS_MAKE_PATH)/bundle.mk

internal-stage::
$(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END)
$(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/MobileGoose.plist$(ECHO_END)
5 changes: 5 additions & 0 deletions Prefs/PXMGPRootListController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import <Preferences/PSListController.h>

@interface PXMGPRootListController : PSListController

@end
36 changes: 36 additions & 0 deletions Prefs/PXMGPRootListController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "PXMGPRootListController.h"
#import <Preferences/PSSpecifier.h>

@implementation PXMGPRootListController

- (NSArray *)specifiers {
if (!_specifiers) {
_specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self];
}

return _specifiers;
}

- (void)setPreferenceValue:(NSNumber *)value forNotifyingSwitch:(PSSpecifier *)specifier {
[self setPreferenceValue:value specifier:specifier];
NSNotificationName notificationName;
if ((value.boolValue && (notificationName = [specifier propertyForKey:@"trueNotification"])) ||
(!value.boolValue && (notificationName = [specifier propertyForKey:@"falseNotification"])))
{
CFNotificationCenterPostNotification(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFNotificationName)notificationName,
NULL, NULL, YES
);
}
if ((notificationName = [specifier propertyForKey:@"anyNotification"])) {
[NSUserDefaults.standardUserDefaults synchronize];
CFNotificationCenterPostNotification(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFNotificationName)notificationName,
NULL, NULL, YES
);
}
}

@end
24 changes: 24 additions & 0 deletions Prefs/Resources/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>MobileGoose</string>
<key>CFBundleIdentifier</key>
<string>com.pixelomer.mobilegoose</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>PXMGPRootListController</string>
</dict>
</plist>
71 changes: 71 additions & 0 deletions Prefs/Resources/Root.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<true/>
<key>defaults</key>
<string>com.pixelomer.mobilegoose</string>
<key>key</key>
<string>Enabled</string>
<key>label</key>
<string>Enabled</string>
<key>set</key>
<string>setPreferenceValue:forNotifyingSwitch:</string>
<key>anyNotification</key>
<string>com.pixelomer.mobilegoose/PreferenceChange</string>
</dict>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
<key>label</key>
<string>Gifts</string>
<key>footerText</key>
<string>You can put images and notes inside "/Library/Application Support/MobileGoose" for the goose to bring.</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<true/>
<key>defaults</key>
<string>com.pixelomer.mobilegoose</string>
<key>key</key>
<string>BringImages</string>
<key>label</key>
<string>Bring Images</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<false/>
<key>defaults</key>
<string>com.pixelomer.mobilegoose</string>
<key>key</key>
<string>BringNotes</string>
<key>label</key>
<string>Bring Notes</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<false/>
<key>defaults</key>
<string>com.pixelomer.mobilegoose</string>
<key>key</key>
<string>DisableDefaultGifts</string>
<key>label</key>
<string>Disable Default Gifts</string>
</dict>
</array>
<key>title</key>
<string>MobileGoose</string>
</dict>
</plist>
21 changes: 21 additions & 0 deletions Prefs/entry.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>entry</key>
<dict>
<key>bundle</key>
<string>MobileGoose</string>
<key>cell</key>
<string>PSLinkCell</string>
<key>detail</key>
<string>PXMGPRootListController</string>
<key>icon</key>
<string>icon.png</string>
<key>isController</key>
<true/>
<key>label</key>
<string>MobileGoose</string>
</dict>
</dict>
</plist>
Loading

0 comments on commit be42073

Please sign in to comment.