/* * Five-Icon SpringBoard (FCSB) 0.58-2 by Yanik Magnan * http://r-ch.net/iphone/ Copyright (c) 2008-2009, Yanik Magnan Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "substrate.h" #import #import #include "SpringBoard/SBIconList.h" #include "SpringBoard/SBIcon.h" #include @protocol Tweak - (int) fcsb_maxIconColumns; - (int) fcsb_maxIconRows; - (float) fcsb_leftMarginForIconRowArray:(NSArray *)row; - (void) fcsb_setOrigin:(CGPoint) origin; - (void) fcsb_setAllowJitter:(BOOL) value; - (CGPoint) fcsb_originForIconAtX:(int)x Y:(int)y; @end static BOOL cached30; static BOOL isDock(SBIconList* iL) { return [iL isKindOfClass:NSClassFromString(@"SBButtonBar")]; } static BOOL isEnabled() { // Checks to see if FCSB is enabled. // Note that the code that handles uninstalls and whatnot is separate from the extension, // merely changing the on to off will cause icons to be rearranged as the firmware will // notice the dimensions of the icon matrices are off and will regenerate its settings // plist. NSDictionary* settingsDict = [NSDictionary dictionaryWithContentsOfFile:@"/var/mobile/Library/Preferences/net.r-ch.fcsb.plist"]; if (settingsDict) return [[settingsDict objectForKey:@"Enable"] boolValue]; return YES; } static BOOL isUsingOS3() { // Helper function that returns whether or not the user is using a version // that begins with 3. Currently used to tell whether or not the user should // have wiggly icons. return [[[UIDevice currentDevice] systemVersion] hasPrefix:@"3"]; } static int $SBIconList$maxIconColumns(SBIconList *self, SEL sel) { // The obvious hack everyone would have tried first. Turns out this works, // except the 5th icon overflows onto the second row, which is why we need // the setOrigin hook. if(isDock(self)) return [self fcsb_maxIconColumns]; return 5; } static int $SBIconList$maxIconRows(SBIconList *self, SEL sel) { // I once again vaguely remember stuff going horribly wrong if this wasn't here in 2.x. // This might conflict with other column/row extensions; no idea. I don't use them. :/ if(isDock(self)) return [self fcsb_maxIconRows]; return 4; } static float $SBIconList$leftMarginForIconRowArray$(SBIconList *self, SEL sel, NSArray *row) { // Does not exist on 3.0; I vaguely remember this being required on 2.2.x, so it stays here. // This not existing has no impact on 3.0 visually; setOrigin takes care of itself. if(isDock(self)) return [self fcsb_leftMarginForIconRowArray:row]; return 4.0; } static void $SBIcon$setAllowJitter$(SBIcon *self, SEL sel, BOOL value) { [self fcsb_setAllowJitter:NO]; } static void $SBIcon$setOrigin$(SBIcon *self, SEL sel, CGPoint origin) { // The bulk of what this extension does is here; it places the icons correctly. // Just setting the max columns to 5 will make it use the same spacing as if there // were only 4, making icons overflow and not fit on the screen. This fixes it, // and is filled with magic numbers. id parent = [self superview]; BOOL cachedSuperIsIconList = [parent isKindOfClass:NSClassFromString(@"SBIconList")]; float padding = 0; if (cachedSuperIsIconList) // fix for the 20-icon bug padding = [parent verticalIconPadding]; // Makes it work with SpringJumps. if (cached30 == NO) [self setAllowJitter:NO]; // Initially set the jitter to off if on 2.2.x. CGPoint orig_origin = origin; int x = (int) orig_origin.x; if (cachedSuperIsIconList && !isDock(parent)) { switch(x) { case 17: origin.x = 256; origin.y -= (74+padding); break; case 80: origin.x -= 13; break; case 156: origin.x -= 26; break; case 232: origin.x -= 39; break; } } [self fcsb_setOrigin:origin]; } static CGPoint $SBIconList$originForIconAtX$Y$(SBIconList *self, SEL sel, int x, int y) { // Completely misleading method name. // The "x" and "y" variables are the columns and rows the icons are on, respectively. // Therefore, the icon in the first column would have an x of 0, and the last would be 4. // This needs to be overridden in 3.0 to get the icons to align with Five Icon Dock. if (isDock(self)) return [self fcsb_originForIconAtX:x Y:y]; // Don't touch the dock, let FID deal with that. CGPoint origin; CGPoint orig_origin = [self fcsb_originForIconAtX:x Y:y]; origin.x = 4 + (x * 63); // Apple, why did you remove leftMarginForIconRowArray? frowny pants :( origin.y = orig_origin.y; return origin; } extern "C" void TweakInitialize() { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; if ((objc_getClass("SpringBoard") == nil) || (isEnabled() == NO)) { [pool release]; return; } Class $SBIconList(objc_getClass("SBIconList")); MSHookMessage($SBIconList, @selector(maxIconColumns), (IMP) &$SBIconList$maxIconColumns, "fcsb_"); MSHookMessage($SBIconList, @selector(maxIconRows), (IMP) &$SBIconList$maxIconRows, "fcsb_"); MSHookMessage($SBIconList, @selector(leftMarginForIconRowArray:), (IMP) &$SBIconList$leftMarginForIconRowArray$, "fcsb_"); MSHookMessage($SBIconList, @selector(originForIconAtX:Y:), (IMP) &$SBIconList$originForIconAtX$Y$, "fcsb_"); Class $SBIcon(objc_getClass("SBIcon")); MSHookMessage($SBIcon, @selector(setOrigin:), (IMP) &$SBIcon$setOrigin$, "fcsb_"); // Only disable the wiggle animation on 2.2 to make it more usable cached30 = isUsingOS3(); if (cached30 == NO) { MSHookMessage($SBIcon, @selector(setAllowJitter:), (IMP) &$SBIcon$setAllowJitter$, "fcsb_"); } [pool release]; }