@@ -0,0 +1 @@ | |||
{ Filter = { Bundles = ( "com.apple.springboard" ); }; } |
@@ -0,0 +1,17 @@ | |||
GO_EASY_ON_ME = 1 | |||
ARCHS = arm64 armv7 | |||
include $(THEOS)/makefiles/common.mk | |||
TWEAK_NAME = DuplexCalendar | |||
DuplexCalendar_FILES = Tweak.xm | |||
DuplexCalendar_FRAMEWORKS = CoreTelephony AudioToolbox | |||
include $(THEOS_MAKE_PATH)/tweak.mk | |||
after-install:: | |||
install.exec "killall -9 SpringBoard" | |||
SUBPROJECTS += duplexcalendarprefs | |||
include $(THEOS_MAKE_PATH)/aggregate.mk |
@@ -0,0 +1,147 @@ | |||
#define kScreenWidth [[UIScreen mainScreen] bounds].size.width | |||
#import <AudioToolbox/AudioToolbox.h> | |||
#import <AudioToolbox/AudioServices.h> | |||
@interface SBTodayTableHeaderView : UIView | |||
-(NSString *)lunarDateHeaderString; | |||
@end | |||
@interface SBFLockScreenDateView : UIView | |||
@property (nonatomic, assign) UILabel *duplexCalendarLabel; | |||
@property (nonatomic, assign) SBTodayTableHeaderView *todayHeaderView; | |||
@property (nonatomic, assign) NSString *todayHeaderViewText; | |||
@property bool dateHidden; | |||
-(id)_dateFont; | |||
-(id)_dateColor; | |||
-(BOOL)isDateHidden; | |||
-(void)layoutDuplexCalendarLabel; | |||
@end | |||
@interface _UILegibilityView : UIView | |||
@end | |||
@interface _UILegibilityLabel : _UILegibilityView | |||
@property (nonatomic, assign) NSString* string; | |||
@property (nonatomic, assign) UIFont* font; | |||
@end | |||
extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void); | |||
static NSString *myObserver=@"duplexcalendarObserver"; | |||
static NSString *settingsPath = @"/var/mobile/Library/Preferences/com.gilshahar7.duplexcalendarprefs.plist"; | |||
static NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath]; | |||
static void savePressed(){ | |||
prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath]; | |||
} | |||
static void savePressed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){ | |||
prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath]; | |||
} | |||
static SBTodayTableHeaderView *stattodayHeaderView; | |||
static float originx = 0.0; | |||
static float originy = 0.0; | |||
static float sizewidth = 0.0; | |||
static float sizeheight = 0.0; | |||
%hook SBTodayTableHeaderView | |||
-(SBTodayTableHeaderView *)initWithFrame:(CGRect)arg1{ | |||
stattodayHeaderView = %orig(); | |||
return stattodayHeaderView; | |||
} | |||
%end | |||
%hook SBFLockScreenDateView | |||
%property (nonatomic, assign) UILabel *duplexCalendarLabel; | |||
%property (nonatomic, assign) NSString *todayHeaderViewText; | |||
-(SBFLockScreenDateView *)initWithFrame:(id)arg1{ | |||
SBFLockScreenDateView *origself = %orig(arg1); | |||
if(!self.duplexCalendarLabel){ | |||
self.duplexCalendarLabel = [[UILabel alloc] initWithFrame:CGRectMake(originx-50, originy + 19, sizewidth+100, sizeheight)]; | |||
self.duplexCalendarLabel.font = [[self _dateFont] fontWithSize:16]; | |||
[self addSubview:self.duplexCalendarLabel]; | |||
self.duplexCalendarLabel.textColor = [self _dateColor]; | |||
self.duplexCalendarLabel.textAlignment = 1; | |||
} | |||
return origself; | |||
} | |||
%new | |||
-(void)layoutDuplexCalendarLabel{ | |||
NSString *offsetXTextField = [prefs objectForKey:@"offsetXTextField"]; | |||
NSString *offsetYTextField = [prefs objectForKey:@"offsetYTextField"]; | |||
NSString *FontSizeTextField = [prefs objectForKey:@"FontSizeTextField"]; | |||
if(originx <= 0.0) | |||
{ | |||
UILabel *originalLabel = MSHookIvar<UILabel *>(self, "_dateLabel"); | |||
originx = originalLabel.frame.origin.x; | |||
originy = originalLabel.frame.origin.y; | |||
sizewidth = originalLabel.frame.size.width; | |||
sizeheight = originalLabel.frame.size.height; | |||
} | |||
[self.duplexCalendarLabel setFrame:CGRectMake(originx-50+ [offsetXTextField floatValue], originy + 19 + [offsetYTextField floatValue], sizewidth+100, sizeheight)]; | |||
UIFont *font = self.duplexCalendarLabel.font; | |||
if([FontSizeTextField floatValue] == 0){ | |||
self.duplexCalendarLabel.font = [font fontWithSize:16.0]; | |||
}else{ | |||
self.duplexCalendarLabel.font = [font fontWithSize:[FontSizeTextField floatValue]]; | |||
} | |||
if(self.duplexCalendarLabel){ | |||
if([self isDateHidden]){ | |||
self.duplexCalendarLabel.hidden = true; | |||
}else{ | |||
self.duplexCalendarLabel.hidden = false; | |||
} | |||
} | |||
} | |||
-(void)_updateLabels{ | |||
[self layoutDuplexCalendarLabel]; | |||
if(!self.todayHeaderViewText){ | |||
self.todayHeaderViewText = [stattodayHeaderView lunarDateHeaderString]; | |||
} | |||
self.duplexCalendarLabel.text = self.todayHeaderViewText; | |||
%orig; | |||
} | |||
-(void)_layoutDateLabel { | |||
[self layoutDuplexCalendarLabel]; | |||
%orig; | |||
_UILegibilityLabel *originalLegibilityLabel = MSHookIvar<_UILegibilityLabel *>(self, "_legibilityDateLabel"); | |||
[originalLegibilityLabel setFrame:CGRectMake(originx, originy - 3, sizewidth, sizeheight)]; | |||
} | |||
-(void)updateFormat{ | |||
[self layoutDuplexCalendarLabel]; | |||
%orig; | |||
} | |||
-(void)layoutSubviews { | |||
[self layoutDuplexCalendarLabel]; | |||
%orig; | |||
} | |||
-(void)setDateHidden:(bool)arg1{ | |||
%orig(arg1); | |||
if(self.duplexCalendarLabel){ | |||
self.duplexCalendarLabel.hidden = arg1; | |||
} | |||
} | |||
%end | |||
%ctor{ | |||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), | |||
(void*)myObserver, | |||
savePressed, | |||
CFSTR("duplexcalendar.savepressed"), | |||
NULL, | |||
CFNotificationSuspensionBehaviorDeliverImmediately); | |||
savePressed(); | |||
} |
@@ -0,0 +1,9 @@ | |||
Package: com.gilshahar7.duplexcalendar | |||
Name: DuplexCalendar | |||
Depends: mobilesubstrate | |||
Version: 1.0 | |||
Architecture: iphoneos-arm | |||
Description: Add the alternate calendar label to the LockScreen on iOS 9. | |||
Maintainer: gilshahar7 | |||
Author: gilshahar7 | |||
Section: Tweaks |
@@ -0,0 +1,5 @@ | |||
#import <Preferences/PSListController.h> | |||
@interface DCPRootListController : PSListController | |||
@end |
@@ -0,0 +1,40 @@ | |||
#import <Preferences/PSSpecifier.h> | |||
#include "DCPRootListController.h" | |||
@implementation DCPRootListController | |||
- (id)readPreferenceValue:(PSSpecifier*)specifier { | |||
NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]]; | |||
NSMutableDictionary *settings = [NSMutableDictionary dictionary]; | |||
[settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]]; | |||
return (settings[specifier.properties[@"key"]]) ?: specifier.properties[@"default"]; | |||
} | |||
- (void)setPreferenceValue:(id)value specifier:(PSSpecifier*)specifier { | |||
NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]]; | |||
NSMutableDictionary *settings = [NSMutableDictionary dictionary]; | |||
[settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]]; | |||
[settings setObject:value forKey:specifier.properties[@"key"]]; | |||
[settings writeToFile:path atomically:YES]; | |||
CFStringRef notificationName = (CFStringRef)specifier.properties[@"PostNotification"]; | |||
if (notificationName) { | |||
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), notificationName, NULL, NULL, YES); | |||
} | |||
} | |||
- (NSArray *)specifiers { | |||
if (!_specifiers) { | |||
_specifiers = [[self loadSpecifiersFromPlistName:@"Root" target:self] retain]; | |||
} | |||
return _specifiers; | |||
} | |||
-(void)save | |||
{ | |||
[self.view endEditing:YES]; | |||
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFSTR("duplexcalendar.savepressed"), NULL, NULL, YES); | |||
} | |||
@end |
@@ -0,0 +1,13 @@ | |||
include $(THEOS)/makefiles/common.mk | |||
BUNDLE_NAME = DuplexCalendarPrefs | |||
DuplexCalendarPrefs_FILES = DCPRootListController.m | |||
DuplexCalendarPrefs_INSTALL_PATH = /Library/PreferenceBundles | |||
DuplexCalendarPrefs_FRAMEWORKS = UIKit | |||
DuplexCalendarPrefs_PRIVATE_FRAMEWORKS = Preferences | |||
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/DuplexCalendarPrefs.plist$(ECHO_END) |
@@ -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>DuplexCalendarPrefs</string> | |||
<key>CFBundleIdentifier</key> | |||
<string>com.gilshahar7.duplexcalendarprefs</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>DCPRootListController</string> | |||
</dict> | |||
</plist> |
@@ -0,0 +1,69 @@ | |||
<?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>PSGroupCell</string> | |||
<key>label</key> | |||
<string>DuplexCalendar's Options</string> | |||
</dict> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSEditTextCell</string> | |||
<key>placeholder</key> | |||
<string>0</string> | |||
<key>bestGuess</key> | |||
<string>0</string> | |||
<key>defaults</key> | |||
<string>com.gilshahar7.duplexcalendarprefs</string> | |||
<key>key</key> | |||
<string>offsetXTextField</string> | |||
<key>label</key> | |||
<string>X Offset:</string> | |||
</dict> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSEditTextCell</string> | |||
<key>placeholder</key> | |||
<string>0</string> | |||
<key>bestGuess</key> | |||
<string>0</string> | |||
<key>defaults</key> | |||
<string>com.gilshahar7.duplexcalendarprefs</string> | |||
<key>key</key> | |||
<string>offsetYTextField</string> | |||
<key>label</key> | |||
<string>Y Offset:</string> | |||
</dict> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSEditTextCell</string> | |||
<key>placeholder</key> | |||
<string>16</string> | |||
<key>bestGuess</key> | |||
<string>16</string> | |||
<key>defaults</key> | |||
<string>com.gilshahar7.duplexcalendarprefs</string> | |||
<key>isDecimalPad</key> | |||
<true/> | |||
<key>key</key> | |||
<string>FontSizeTextField</string> | |||
<key>label</key> | |||
<string>Font Size:</string> | |||
</dict> | |||
<dict> | |||
<key>cell</key> | |||
<string>PSButtonCell</string> | |||
<key>label</key> | |||
<string>Save</string> | |||
<key>action</key> | |||
<string>save</string> | |||
</dict> | |||
</array> | |||
<key>title</key> | |||
<string>DuplexCalendar</string> | |||
</dict> | |||
</plist> |
@@ -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>DuplexCalendarPrefs</string> | |||
<key>cell</key> | |||
<string>PSLinkCell</string> | |||
<key>detail</key> | |||
<string>DCPRootListController</string> | |||
<key>icon</key> | |||
<string>icon.png</string> | |||
<key>isController</key> | |||
<true/> | |||
<key>label</key> | |||
<string>DuplexCalendarPrefs</string> | |||
</dict> | |||
</dict> | |||
</plist> |