Last active
August 29, 2015 13:58
-
-
Save ciiqr/10425684 to your computer and use it in GitHub Desktop.
Bookmarks Bar Layout for BMarks Bar - Chrome
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// BookmarksBar Layout code from BMarks Bar - Chrome (iOS Tweak) | |
// User Settings | |
// DISPLAY_OTHER_BOOKMARKS_ITEM = [YES|NO] | |
// DISPLAY_REST_BOOKMARKS_ITEM = [YES|NO] | |
// ... | |
// Application Constants | |
// #define kEdgeSpacing 9.f | |
// #define kItemSpacing 10.f | |
// ... | |
// Bookmark Bars layout subviews | |
// - Determines Bookmark Sizes | |
// - Spaces out items appropriately | |
// - Add/Remove bookmarks on rotate & when bookmarks change | |
// - Dismisses folder popovers (future, reposition them) | |
// - Adds a "Rest" item for any bookmarks that do not fit (Dependent on User Settings) | |
// - Adds a right aligned, always there "Other" bookmarks item (Dependent on User Settings) | |
- (void)layoutSubviews | |
{ | |
// Super | |
[super layoutSubviews]; | |
// Bookmarks | |
NSArray *items = _items; | |
// Number of Bookmarks | |
NSUInteger itemsCount = items.count; | |
// xOffset of Bookamrks | |
CGFloat xOffset = kEdgeSpacing; | |
// Bar Width | |
CGFloat barWidth = self.bounds.size.width; | |
// Add Other Item | |
if (DISPLAY_OTHER_BOOKMARKS_ITEM && itemsCount > 0) | |
{ | |
// Retrieve From Items (Should always be the last Item, if DISPLAY_OTHER_BOOKMARKS_ITEM is YES) | |
WVBookmarkItem *otherBookmarkItem = [items lastObject]; // is the Other Bookmark Item | |
// Others View | |
UIView *otherView = otherBookmarkItem.customView; | |
// Position | |
CGRect otherFrame = otherView.frame; | |
CGFloat otherWidth = otherFrame.size.width + kEdgeSpacing; | |
otherFrame.origin.x = barWidth - otherWidth; | |
otherView.frame = otherFrame; | |
// Reduce Bar Width So Items Dont Over Lap Other | |
barWidth -= otherWidth; | |
// Prevent loop Messing with Other Item | |
itemsCount--; | |
} | |
// Create Rest Item (So we know Size & Can Add it if Needed) | |
CGFloat restItemWidth = 0; | |
if (DISPLAY_REST_BOOKMARKS_ITEM && itemsCount > 0) | |
{ | |
if (!_restItem) // If it doesn't exist, create | |
_restItem = [WVBookmarkItem restItemTypeWithTarget:self]; | |
// Rest View | |
UIView *restView = _restItem.customView; | |
// Position | |
CGRect restFrame = restView.frame; | |
restItemWidth = restFrame.size.width; // Rest Includes its Own Tappable Spacing | |
restFrame.origin.x = barWidth - restItemWidth; | |
restView.frame = restFrame; | |
} | |
// Add Items | |
for (NSUInteger index = 0; index < itemsCount; index++) | |
{ | |
// BookmarkItem | |
WVBookmarkItem *bookmarkItem = items[index]; | |
UIView *bookmarkView = bookmarkItem.customView; | |
// If bookmarkView in not in superView, add to superview (For When Rotating and adding more items) | |
if (!bookmarkView.superview) | |
[self addSubview:bookmarkView]; | |
// Item Width & Location | |
CGRect itemFrame = bookmarkView.frame; | |
CGFloat itemWidth = itemFrame.size.width; | |
itemFrame.origin.x = xOffset; | |
bookmarkView.frame = itemFrame; | |
// Set the next items X Offset | |
xOffset += (itemWidth + kItemSpacing); | |
BOOL fitsOnBar = (xOffset < barWidth); | |
BOOL sufficientSpaceForRestItem = ((barWidth - xOffset) >= restItemWidth); | |
BOOL lastItem = ((index + 1) == itemsCount); | |
// Rest Item is Not Needed | |
if (lastItem && fitsOnBar) | |
{ | |
// Remove if it was previously on the bar | |
[_restItem.customView removeFromSuperview]; | |
// Popover is Showing Rest Item | |
if ([_popover isPopoverVisible] && (((WVBookmarksTVC *)_popover.contentViewController).bookmarkItem == _restItem)) | |
{ | |
// Dismiss Popover | |
if ([_popover.delegate popoverControllerShouldDismissPopover:_popover]) | |
{ | |
[_popover dismissPopoverAnimated:NO]; | |
[_popover.delegate popoverControllerDidDismissPopover:_popover]; | |
} | |
} | |
} | |
if (fitsOnBar && (sufficientSpaceForRestItem || lastItem)) | |
{ | |
// Items is going to be added to the bar... | |
// Dismiss OR Reposition Popover (W.I.P.) | |
if (lastItem && _popover.isPopoverVisible) | |
{ | |
#ifdef TESTING_POPOVER_REPOSITION | |
// is Normal Bar Item... I Think (or rest.children.children OR Lower (FixWith WVBookmarkItem - (BOOL)reccursiveChildrenContainsItem:(WVBookmarkItem *)item)) | |
[_popover repositionPopoverFromRect:bookmarkItem.customView.frame | |
inView:bookmarkItem.customView | |
permittedArrowDirections:UIPopoverArrowDirectionUp | |
animated:YES]; | |
#else | |
// Dismiss Popover | |
if ([_popover.delegate popoverControllerShouldDismissPopover:_popover]) | |
{ | |
[_popover dismissPopoverAnimated:NO]; | |
[_popover.delegate popoverControllerDidDismissPopover:_popover]; | |
} | |
#endif // TESTING_POPOVER_REPOSITION // | |
} | |
} | |
else // Item wont be displayed, add it (and the rest) to the restItem | |
{ | |
// Get The Rest of The Items | |
NSArray *remainingItems = [items subarrayWithRange:NSMakeRange(index, itemsCount - index)]; | |
// Remove Items Views From Bar | |
[remainingItems enumerateObjectsUsingBlock: ^(WVBookmarkItem *remainingBookmarkItem, NSUInteger idx, BOOL *stop) | |
{ | |
[remainingBookmarkItem.customView removeFromSuperview]; | |
}]; | |
// Set the Rest Items Children to the Remaining Items | |
_restItem.children = remainingItems; | |
// Add RestItem if it isn't already on the bar | |
if (!_restItem.customView.superview) | |
[self addSubview:_restItem.customView]; | |
// #warning BELOW | |
// For Right Now we are going to dismiss on rotate (but the infastructure is here NOT too, just have to figure out why it does not position the popover properly) | |
// ^^ May have to create a new popover with rotate | |
// if Popover is Visible (restItem, display its items) | |
// ^^ If Not Rest But is now inside rest dismiss | |
if ([_popover isPopoverVisible]) | |
{ | |
WVBookmarkItem *popoverBookmarkItem = ((WVBookmarksTVC *)_popover.contentViewController).bookmarkItem; | |
if (popoverBookmarkItem == _restItem) | |
{ | |
// Dismiss | |
[_popover dismissPopoverAnimated:NO]; | |
// ReShow Rest Popover with new items if it was visible before | |
if (_restItem.children.count > 0) | |
{ | |
#ifdef TESTING_POPOVER_REPOSITION | |
WVBookmarksTVC *newRestVC = [[WVBookmarksTVC alloc] initWithBookmarkItem:_restItem delegate:self]; | |
_popover.contentViewController = newRestVC; | |
// Set Popover Size Based on ViewController Size | |
_popover.popoverContentSize = newRestVC.contentSizeForViewInPopover; | |
// Present Popover | |
UIView *customView = _currentBookmarkItem.customView; | |
[_popover presentPopoverFromRect:customView.frame | |
inView:customView.superview | |
permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO]; | |
#else | |
// Dismiss Popover | |
if ([_popover.delegate popoverControllerShouldDismissPopover:_popover]) | |
{ | |
[_popover dismissPopoverAnimated:NO]; | |
[_popover.delegate popoverControllerDidDismissPopover:_popover]; | |
} | |
#endif // TESTING_POPOVER_REPOSITION // | |
} | |
} | |
// if Item is in Rest then dismiss | |
else if ([_restItem.children containsObject:popoverBookmarkItem]) | |
{ | |
// Dismiss Popover | |
if ([_popover.delegate popoverControllerShouldDismissPopover:_popover]) | |
{ | |
[_popover dismissPopoverAnimated:NO]; | |
[_popover.delegate popoverControllerDidDismissPopover:_popover]; | |
} | |
} | |
// is Normal Bar Item... I Think (or rest.children.children OR Lower (FixWith WVBookmarkItem - (BOOL)reccursiveChildrenContainsItem:(WVBookmarkItem *)item)) | |
else //if item is on bar & visible (has SuperView) | |
{ | |
#ifdef TESTING_POPOVER_REPOSITION | |
// is Normal Bar Item... I Think (or rest.children.children OR Lower (FixWith WVBookmarkItem - (BOOL)reccursiveChildrenContainsItem:(WVBookmarkItem *)item)) | |
[_popover repositionPopoverFromRect:bookmarkItem.customView.frame | |
inView:bookmarkItem.customView | |
permittedArrowDirections:UIPopoverArrowDirectionUp | |
animated:YES]; | |
#else | |
// Dismiss Popover | |
if ([_popover.delegate popoverControllerShouldDismissPopover:_popover]) | |
{ | |
[_popover dismissPopoverAnimated:NO]; | |
[_popover.delegate popoverControllerDidDismissPopover:_popover]; | |
} | |
#endif // TESTING_POPOVER_REPOSITION // | |
} | |
} | |
break; // Because The Rest of the items are in the "rest item" | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment