X-Git-Url: https://git.saurik.com/winterboard.git/blobdiff_plain/a067a975d024c68e2cfd945dd819945c7e37adc9..2cb720e94f9d325cff69241a4b25bb4bdd1516bf:/Library.mm diff --git a/Library.mm b/Library.mm index 3ba7137..3904ea9 100644 --- a/Library.mm +++ b/Library.mm @@ -121,6 +121,7 @@ MSClassHook(UIImage) MSMetaClassHook(UIImage) MSClassHook(UINavigationBar) MSClassHook(UIToolbar) +MSClassHook(UIStatusBarTimeItemView) MSClassHook(CKBalloonView) MSClassHook(CKMessageCell) @@ -141,6 +142,7 @@ MSClassHook(SBDockIconListView) MSClassHook(SBIcon) MSClassHook(SBIconBadge) MSClassHook(SBIconBadgeFactory) +MSClassHook(SBIconContentView) MSClassHook(SBIconController) MSClassHook(SBIconLabel) MSClassHook(SBIconList) @@ -159,13 +161,14 @@ MSClassHook(SBWidgetApplicationIcon) extern "C" void WKSetCurrentGraphicsContext(CGContextRef); -__attribute__((__constructor__)) -static void MSFixClass() { - if ($SBIcon == nil) - $SBIcon = objc_getClass("SBIconView"); +static struct MSFixClass { MSFixClass() { + $SBIcon = objc_getClass("SBIconView") ?: $SBIcon; + + if ($SBIconList == nil) + $SBIconList = objc_getClass("SBIconListView"); if ($CKTranscriptController == nil) $CKTranscriptController = objc_getClass("mSMSMessageTranscriptController"); -} +} } MSFixClass; static bool IsWild_; static bool Four_($SBDockIconListView != nil); @@ -200,7 +203,7 @@ static BOOL (*_GSFontGetUseLegacyFontMetrics)(); static bool Debug_ = false; static bool UIDebug_ = false; static bool Engineer_ = false; -static bool SummerBoard_ = true; +static bool SummerBoard_ = false; static bool SpringBoard_; static UIImage *(*_UIApplicationImageWithName)(NSString *name); @@ -676,6 +679,35 @@ MSInstanceMessageHook2(NSString *, NSBundle, pathForResource,ofType, NSString *, } // }}} +static void $drawLabel$(NSString *label, CGRect rect, NSString *style, NSString *custom) { + bool ellipsis(false); + float max = rect.size.width - 11, width; + width: + width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; + + if (width > max) { + size_t length([label length]); + float spacing((width - max) / (length - 1)); + + if (spacing > 1.25) { + ellipsis = true; + label = [label substringToIndex:(length - 1)]; + goto width; + } + + style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; + } + + if (ellipsis) + label = [label stringByAppendingString:@"..."]; + + if (custom != nil) + style = [style stringByAppendingString:custom]; + + CGSize size = [label sizeWithStyle:style forWidth:rect.size.width]; + [label drawAtPoint:CGPointMake((rect.size.width - size.width) / 2 + rect.origin.x, rect.origin.y) withStyle:style]; +} + static struct WBStringDrawingState { WBStringDrawingState *next_; unsigned count_; @@ -683,7 +715,9 @@ static struct WBStringDrawingState { NSString *info_; } *stringDrawingState_; -MSInstanceMessageHook6(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode,letterSpacing,includeEmoji, CGPoint, point, float, width, UIFont *, font, int, mode, float, spacing, BOOL, emoji) { +MSInstanceMessageHook6(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreakMode,letterSpacing,includeEmoji, CGPoint, point, float, width, UIFont *, font, UILineBreakMode, mode, float, spacing, BOOL, emoji) { + //NSLog(@"XXX: @\"%@\" %g", self, spacing); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) return MSOldCall(point, width, font, mode, spacing, emoji); @@ -703,7 +737,11 @@ MSInstanceMessageHook6(CGSize, NSString, drawAtPoint,forWidth,withFont,lineBreak return CGSizeZero; } -MSInstanceMessageHook7(CGSize, NSString, _drawInRect,withFont,lineBreakMode,alignment,lineSpacing,includeEmoji,truncationRect, CGRect, rect, UIFont *, font, int, mode, int, alignment, float, spacing, BOOL, emoji, CGRect, truncation) { +extern "C" NSString *NSStringFromCGRect(CGRect rect); + +MSInstanceMessageHook7(CGSize, NSString, _drawInRect,withFont,lineBreakMode,alignment,lineSpacing,includeEmoji,truncationRect, CGRect, rect, UIFont *, font, UILineBreakMode, mode, UITextAlignment, alignment, float, spacing, BOOL, emoji, CGRect, truncation) { + //NSLog(@"XXX: &\"%@\" %@ \"%@\" %u %u %g %u %@", self, NSStringFromCGRect(rect), font, mode, alignment, spacing, emoji, NSStringFromCGRect(truncation)); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); @@ -717,13 +755,34 @@ MSInstanceMessageHook7(CGSize, NSString, _drawInRect,withFont,lineBreakMode,alig if (info == nil) return MSOldCall(rect, font, mode, alignment, spacing, emoji, truncation); + NSString *textAlign; + switch (alignment) { + default: + case UITextAlignmentLeft: + textAlign = @"left"; + break; + case UITextAlignmentCenter: + textAlign = @"center"; + break; + case UITextAlignmentRight: + textAlign = @"right"; + break; + } + NSString *base(state->base_ ?: @""); - NSString *align(@"text-align: center"); - [self drawInRect:rect withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], align, base, info]]; + NSString *extra([NSString stringWithFormat:@"text-align: %@", textAlign]); + + if (true) + $drawLabel$(self, rect, [NSString stringWithFormat:@"%@;%@", [font markupDescription], base], info); + else + [self drawInRect:rect withStyle:[NSString stringWithFormat:@"%@;%@;%@;%@", [font markupDescription], extra, base, info]]; + return CGSizeZero; } -MSInstanceMessageHook4(CGSize, NSString, sizeWithFont,forWidth,lineBreakMode,letterSpacing, UIFont *, font, float, width, int, mode, float, spacing) { +MSInstanceMessageHook4(CGSize, NSString, sizeWithFont,forWidth,lineBreakMode,letterSpacing, UIFont *, font, float, width, UILineBreakMode, mode, float, spacing) { + //NSLog(@"XXX: #\"%@\" \"%@\" %g %u %g", self, font, width, mode, spacing); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) return MSOldCall(font, width, mode, spacing); @@ -743,6 +802,8 @@ MSInstanceMessageHook4(CGSize, NSString, sizeWithFont,forWidth,lineBreakMode,let } MSInstanceMessageHook1(CGSize, NSString, sizeWithFont, UIFont *, font) { + //NSLog(@"XXX: ?\"%@\"", self); + WBStringDrawingState *state(stringDrawingState_); if (state == NULL) return MSOldCall(font); @@ -794,6 +855,19 @@ MSInstanceMessageHook1(UIImage *, SBCalendarApplicationIcon, generateIconImage, return image; } +MSInstanceMessageHook1(UIImage *, UIStatusBarTimeItemView, contentsImageForStyle, int, style) { + WBStringDrawingState timeState = {NULL, 0, @"" + "color: white;" + , @"TimeStyle"}; + + stringDrawingState_ = &timeState; + + UIImage *image(MSOldCall(style)); + + stringDrawingState_ = NULL; + return image; +} + MSHook(void, SBCalendarIconContentsView$drawRect$, SBCalendarIconContentsView *self, SEL sel, CGRect rect) { NSBundle *bundle([NSBundle mainBundle]); @@ -1194,7 +1268,7 @@ extern "C" NSString *UIStyleStringFromColor(CGColorRef);*/ WBDelegate(time_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"TimeStyle"]) { BOOL &_mode(MSHookIvar(view_, "_mode"));; @@ -1241,7 +1315,7 @@ WBDelegate(time_) WBDelegate(badge_) -- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(int)mode { +- (CGSize) drawAtPoint:(CGPoint)point forWidth:(float)width withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)mode { if (NSString *custom = [Info_ objectForKey:@"BadgeStyle"]) { [badge_ drawAtPoint:point withStyle:[NSString stringWithFormat:@"" "font-family: Helvetica; " @@ -1277,8 +1351,12 @@ MSInstanceMessageHook0(id, SBIcon, initWithDefaultSize) { if (NSNumber *number = [Info_ objectForKey:@"IconAlpha"]) { // XXX: note: this is overridden above, which is silly float alpha([number floatValue]); - [self setIconImageAlpha:alpha]; - [self setIconLabelAlpha:alpha]; + if ([self respondsToSelector:@selector(setIconImageAlpha:)]) + [self setIconImageAlpha:alpha]; + if ([self respondsToSelector:@selector(setIconLabelAlpha:)]) + [self setIconLabelAlpha:alpha]; + if ([self respondsToSelector:@selector(setAlpha:)]) + [self setAlpha:alpha]; } } return self; } @@ -1416,31 +1494,53 @@ MSHook(void, SBIconList$setFrame$, SBIconList *self, SEL sel, CGRect frame) { _SBIconList$setFrame$(self, sel, frame); } -MSHook(void, SBIconController$noteNumberOfIconListsChanged, SBIconController *self, SEL sel) { - SBIconModel *&_iconModel(MSHookIvar(self, "_iconModel")); - NSArray *lists([_iconModel iconLists]); +static void $addPerPageView$(unsigned i, UIView *list) { + NSString *path($getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Page%u.png", i]])); + if (path == nil) + return; + NSArray *subviews([list subviews]); + + WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]); + if (view == nil || ![view wb$isWBImageView]) { + view = [[[WBImageView alloc] init] autorelease]; + [list insertSubview:view atIndex:0]; + } + + UIImage *image([UIImage imageWithContentsOfFile:path]); + + CGRect frame([view frame]); + frame.size = [image size]; + [view setFrame:frame]; + + [view setImage:image]; + [view wb$updateFrame]; +} + +static void $addPerPageViews$(NSArray *lists) { for (unsigned i(0), e([lists count]); i != e; ++i) - if (NSString *path = $getTheme$([NSArray arrayWithObject:[NSString stringWithFormat:@"Page%u.png", i]])) { - SBIconList *list([lists objectAtIndex:i]); - NSArray *subviews([list subviews]); - - WBImageView *view([subviews count] == 0 ? nil : [subviews objectAtIndex:0]); - if (view == nil || ![view wb$isWBImageView]) { - view = [[[WBImageView alloc] init] autorelease]; - [list insertSubview:view atIndex:0]; - } + $addPerPageView$(i, [lists objectAtIndex:i]); +} - UIImage *image([UIImage imageWithContentsOfFile:path]); +MSInstanceMessageHook0(void, SBIconController, updateNumberOfRootIconLists) { + NSArray *&_rootIconLists(MSHookIvar(self, "_rootIconLists")); + $addPerPageViews$(_rootIconLists); + return MSOldCall(); +} - CGRect frame([view frame]); - frame.size = [image size]; - [view setFrame:frame]; +MSInstanceMessageHook0(void, SBIconContentView, layoutSubviews) { + MSOldCall(); - [view setImage:image]; - [view wb$updateFrame]; - } + if (SBIconController *controller = [$SBIconController sharedInstance]) { + UIView *&_dockContainerView(MSHookIvar(controller, "_dockContainerView")); + if (&_dockContainerView != NULL) + [[_dockContainerView superview] bringSubviewToFront:_dockContainerView]; + } +} +MSHook(void, SBIconController$noteNumberOfIconListsChanged, SBIconController *self, SEL sel) { + SBIconModel *&_iconModel(MSHookIvar(self, "_iconModel")); + $addPerPageViews$([_iconModel iconLists]); return _SBIconController$noteNumberOfIconListsChanged(self, sel); } @@ -1525,8 +1625,6 @@ MSInstanceMessageHook2(CGSize, WebCoreFrameBridge, renderedSizeOfNode,constraine // }}} MSInstanceMessage1(void, SBIconLabel, drawRect, CGRect, rect) { - CGRect bounds = [self bounds]; - static Ivar drawMoreLegibly = object_getInstanceVariable(self, "_drawMoreLegibly", NULL); int docked; @@ -1549,46 +1647,23 @@ MSInstanceMessage1(void, SBIconLabel, drawRect, CGRect, rect) { else if (docked) style = [style stringByAppendingString:@"text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px; "]; - bool ellipsis(false); - float max = [self frame].size.width - 11, width; - width: - width = [(ellipsis ? [label stringByAppendingString:@"..."] : label) sizeWithStyle:style forWidth:320].width; - - if (width > max) { - size_t length([label length]); - float spacing((width - max) / (length - 1)); - - if (spacing > 1.25) { - ellipsis = true; - label = [label substringToIndex:(length - 1)]; - goto width; - } - - style = [style stringByAppendingString:[NSString stringWithFormat:@"letter-spacing: -%f; ", spacing]]; - } - - if (ellipsis) - label = [label stringByAppendingString:@"..."]; - - if (NSString *custom = [Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]) - style = [style stringByAppendingString:custom]; + NSString *custom([Info_ objectForKey:(docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle")]); - CGSize size = [label sizeWithStyle:style forWidth:bounds.size.width]; - [label drawAtPoint:CGPointMake((bounds.size.width - size.width) / 2, 0) withStyle:style]; + $drawLabel$(label, [self bounds], style, custom); } MSInstanceMessage0(CGImageRef, SBIconLabel, buildLabelImage) { bool docked((MSHookIvar(self, "_inDock") & 0x2) != 0); - WBStringDrawingState labelState = {NULL, 0, [NSString stringWithFormat:@"" - "color: %@;" - , - (docked || !SummerBoard_ ? @"white" : @"#b3b3b3") - ], docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle"}; + WBStringDrawingState labelState = {NULL, 0, @"" + "color: white;" + , docked ? @"DockedIconLabelStyle" : @"UndockedIconLabelStyle"}; stringDrawingState_ = &labelState; + //NSLog(@"XXX: +"); CGImageRef image(MSOldCall()); + //NSLog(@"XXX: -"); stringDrawingState_ = NULL; return image; @@ -1778,7 +1853,7 @@ MSHook(bool, _Z24GetFileNameForThisActionmPcRb, unsigned long a0, char *a1, bool NSString *path([NSString stringWithFormat:@"%@/UISounds/%@", theme, file]); if ([Manager_ fileExistsAtPath:path]) { strcpy(a1, [path UTF8String]); - continue; + break; } } } @@ -1847,6 +1922,7 @@ static void NSString$drawAtPoint$withStyle$(NSString *self, SEL _cmd, CGPoint po WKSetCurrentGraphicsContext(UIGraphicsGetCurrentContext()); if (style == nil || [style length] == 0) style = @"font-family: Helvetica; font-size: 12px"; + //NSLog(@"XXX:draw(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]); return [[WBMarkup sharedMarkup] drawString:self atPoint:point withStyle:style]; } @@ -1860,14 +1936,11 @@ static void NSString$drawInRect$withStyle$(NSString *self, SEL _cmd, CGRect rect static CGSize NSString$sizeWithStyle$forWidth$(NSString *self, SEL _cmd, NSString *style, float width) { if (style == nil || [style length] == 0) style = @"font-family: Helvetica; font-size: 12px"; + //NSLog(@"XXX:size(%@)", [style stringByReplacingOccurrencesOfString:@"\n" withString:@" "]); return [[WBMarkup sharedMarkup] sizeOfString:self withStyle:style forWidth:width]; } static void SBInitialize() { - class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16"); - class_addMethod($NSString, @selector(drawInRect:withStyle:), (IMP) &NSString$drawInRect$withStyle$, "v28@0:4{CGRect={CGSize=ff}{CGSize=ff}}8@24"); - class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12"); - if (SummerBoard_) { WBRename(SBApplication, pathForIcon, pathForIcon); WBRename(SBApplicationIcon, icon, icon); @@ -1885,7 +1958,7 @@ static void SBInitialize() { WBRename(SBDockIconListView, setFrame:, setFrame$); MSHookMessage(object_getClass($SBDockIconListView), @selector(shouldShowNewDock), &$SBDockIconListView$shouldShowNewDock, &_SBDockIconListView$shouldShowNewDock); - if (kCFCoreFoundationVersionNumber < 600) + if (kCFCoreFoundationVersionNumber < 600 || SummerBoard_) WBRename(SBIconLabel, drawRect:, drawRect$); else WBRename(SBIconLabel, buildLabelImage, buildLabelImage); @@ -1935,6 +2008,9 @@ MSInitialize { if (NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/User/Library/Preferences/com.saurik.WinterBoard.plist"]]) { if (NSNumber *value = [settings objectForKey:@"SummerBoard"]) SummerBoard_ = [value boolValue]; + else + SummerBoard_ = true; + if (NSNumber *value = [settings objectForKey:@"Debug"]) Debug_ = [value boolValue]; if (NSNumber *value = [settings objectForKey:@"RecordUI"]) @@ -2029,6 +2105,10 @@ MSInitialize { // }}} // UIKit {{{ if ([NSBundle bundleWithIdentifier:@"com.apple.UIKit"] != nil) { + class_addMethod($NSString, @selector(drawAtPoint:withStyle:), (IMP) &NSString$drawAtPoint$withStyle$, "v20@0:4{CGPoint=ff}8@16"); + class_addMethod($NSString, @selector(drawInRect:withStyle:), (IMP) &NSString$drawInRect$withStyle$, "v28@0:4{CGRect={CGSize=ff}{CGSize=ff}}8@24"); + class_addMethod($NSString, @selector(sizeWithStyle:forWidth:), (IMP) &NSString$sizeWithStyle$forWidth$, "{CGSize=ff}16@0:4@8f12"); + struct nlist nl[6]; memset(nl, 0, sizeof(nl)); nl[0].n_un.n_name = (char *) "__UIApplicationImageWithName";