OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" | 5 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" |
6 | 6 |
7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
8 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
9 #include "chrome/browser/bookmarks/bookmark_model.h" | 9 #include "chrome/browser/bookmarks/bookmark_model.h" |
10 #include "chrome/browser/bookmarks/bookmark_utils.h" | 10 #include "chrome/browser/bookmarks/bookmark_utils.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 copy:(BOOL)copy; | 203 copy:(BOOL)copy; |
204 | 204 |
205 @end | 205 @end |
206 | 206 |
207 @interface BookmarkButton (BookmarkBarFolderMenuHighlighting) | 207 @interface BookmarkButton (BookmarkBarFolderMenuHighlighting) |
208 | 208 |
209 // Make the button's border frame always appear when |forceOn| is YES, | 209 // Make the button's border frame always appear when |forceOn| is YES, |
210 // otherwise only border the button when the mouse is inside the button. | 210 // otherwise only border the button when the mouse is inside the button. |
211 - (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn; | 211 - (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn; |
212 | 212 |
213 // On 10.6 event dispatch for an NSButtonCell's | |
214 // showsBorderOnlyWhileMouseInside seems broken if scrolling the | |
215 // view that contains the button. It appears that a mouseExited: | |
216 // gets lost, so the button stays highlit forever. We accomodate | |
217 // here. | |
218 - (void)toggleButtonBorderingWhileMouseInside; | |
219 @end | 213 @end |
220 | 214 |
221 @implementation BookmarkButton (BookmarkBarFolderMenuHighlighting) | 215 @implementation BookmarkButton (BookmarkBarFolderMenuHighlighting) |
222 | 216 |
223 - (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn { | 217 - (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn { |
224 [self setShowsBorderOnlyWhileMouseInside:!forceOn]; | 218 [self setShowsBorderOnlyWhileMouseInside:!forceOn]; |
225 [self setNeedsDisplay]; | 219 [self setNeedsDisplay]; |
226 } | 220 } |
227 | 221 |
228 - (void)toggleButtonBorderingWhileMouseInside { | |
229 BOOL toggle = [self showsBorderOnlyWhileMouseInside]; | |
230 [self setShowsBorderOnlyWhileMouseInside:!toggle]; | |
231 [self setShowsBorderOnlyWhileMouseInside:toggle]; | |
232 } | |
233 | |
234 @end | 222 @end |
235 | 223 |
236 @implementation BookmarkBarFolderController | 224 @implementation BookmarkBarFolderController |
237 | 225 |
238 @synthesize subFolderGrowthToRight = subFolderGrowthToRight_; | 226 @synthesize subFolderGrowthToRight = subFolderGrowthToRight_; |
239 | 227 |
240 - (id)initWithParentButton:(BookmarkButton*)button | 228 - (id)initWithParentButton:(BookmarkButton*)button |
241 parentController:(BookmarkBarFolderController*)parentController | 229 parentController:(BookmarkBarFolderController*)parentController |
242 barController:(BookmarkBarController*)barController { | 230 barController:(BookmarkBarController*)barController { |
243 NSString* nibPath = | 231 NSString* nibPath = |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 | 846 |
859 // End a scrolling timer. Can be called excessively with no harm. | 847 // End a scrolling timer. Can be called excessively with no harm. |
860 - (void)endScroll { | 848 - (void)endScroll { |
861 if (scrollTimer_) { | 849 if (scrollTimer_) { |
862 [scrollTimer_ invalidate]; | 850 [scrollTimer_ invalidate]; |
863 scrollTimer_ = nil; | 851 scrollTimer_ = nil; |
864 verticalScrollDelta_ = 0; | 852 verticalScrollDelta_ = 0; |
865 } | 853 } |
866 } | 854 } |
867 | 855 |
| 856 - (int)indexOfButton:(BookmarkButton*)button { |
| 857 if (button == nil) |
| 858 return -1; |
| 859 int index = [buttons_ indexOfObject:button]; |
| 860 return (index == NSNotFound) ? -1 : index; |
| 861 } |
| 862 |
| 863 - (BookmarkButton*)buttonAtIndex:(int)which { |
| 864 if (which < 0 || which >= [self buttonCount]) |
| 865 return nil; |
| 866 return [buttons_ objectAtIndex:which]; |
| 867 } |
| 868 |
| 869 // Private, called by performOneScroll only. |
| 870 // If the button at index contains the mouse it will select it and return YES. |
| 871 // Otherwise returns NO. |
| 872 - (BOOL)selectButtonIfHoveredAtIndex:(int)index { |
| 873 BookmarkButton *btn = [self buttonAtIndex:index]; |
| 874 if ([[btn cell] isMouseReallyInside]) { |
| 875 buttonThatMouseIsIn_ = btn; |
| 876 [self setSelectedButtonByIndex:index]; |
| 877 return YES; |
| 878 } |
| 879 return NO; |
| 880 } |
| 881 |
868 // Perform a single scroll of the specified amount. | 882 // Perform a single scroll of the specified amount. |
869 - (void)performOneScroll:(CGFloat)delta { | 883 - (void)performOneScroll:(CGFloat)delta { |
870 if (delta == 0.0) | 884 if (delta == 0.0) |
871 return; | 885 return; |
872 CGFloat finalDelta = [self determineFinalScrollDelta:delta]; | 886 CGFloat finalDelta = [self determineFinalScrollDelta:delta]; |
873 if (finalDelta > 0.0 || finalDelta < 0.0) { | 887 if (finalDelta == 0.0) |
874 if (buttonThatMouseIsIn_) | 888 return; |
875 [buttonThatMouseIsIn_ toggleButtonBorderingWhileMouseInside]; | 889 int index = [self indexOfButton:buttonThatMouseIsIn_]; |
876 NSRect windowFrame = [[self window] frame]; | 890 // Check for a current mouse-initiated selection. |
877 NSSize newSize = NSMakeSize(NSWidth(windowFrame), 0.0); | 891 BOOL maintainHoverSelection = |
878 [self adjustWindowLeft:windowFrame.origin.x | 892 (buttonThatMouseIsIn_ && |
879 size:newSize | 893 [[buttonThatMouseIsIn_ cell] isMouseReallyInside] && |
880 scrollingBy:finalDelta]; | 894 selectedIndex_ != -1 && |
| 895 index == selectedIndex_); |
| 896 NSRect windowFrame = [[self window] frame]; |
| 897 NSSize newSize = NSMakeSize(NSWidth(windowFrame), 0.0); |
| 898 [self adjustWindowLeft:windowFrame.origin.x |
| 899 size:newSize |
| 900 scrollingBy:finalDelta]; |
| 901 // We have now scrolled. |
| 902 if (!maintainHoverSelection) |
| 903 return; |
| 904 // Is mouse still in the same hovered button? |
| 905 if ([[buttonThatMouseIsIn_ cell] isMouseReallyInside]) |
| 906 return; |
| 907 // The finalDelta scroll direction will tell us us whether to search up or |
| 908 // down the buttons array for the newly hovered button. |
| 909 if (finalDelta < 0.0) { // Scrolled up, so search backwards for new hover. |
| 910 index--; |
| 911 while (index >= 0) { |
| 912 if ([self selectButtonIfHoveredAtIndex:index]) |
| 913 return; |
| 914 index--; |
| 915 } |
| 916 } else { // Scrolled down, so search forward for new hovered button. |
| 917 index++; |
| 918 int btnMax = [self buttonCount]; |
| 919 while (index < btnMax) { |
| 920 if ([self selectButtonIfHoveredAtIndex:index]) |
| 921 return; |
| 922 index++; |
| 923 } |
881 } | 924 } |
882 } | 925 } |
883 | 926 |
884 - (CGFloat)determineFinalScrollDelta:(CGFloat)delta { | 927 - (CGFloat)determineFinalScrollDelta:(CGFloat)delta { |
885 if ((delta > 0.0 && ![scrollUpArrowView_ isHidden]) || | 928 if ((delta > 0.0 && ![scrollUpArrowView_ isHidden]) || |
886 (delta < 0.0 && ![scrollDownArrowView_ isHidden])) { | 929 (delta < 0.0 && ![scrollDownArrowView_ isHidden])) { |
887 NSWindow* window = [self window]; | 930 NSWindow* window = [self window]; |
888 NSRect windowFrame = [window frame]; | 931 NSRect windowFrame = [window frame]; |
889 NSScreen* screen = [window screen]; | 932 NSScreen* screen = [window screen]; |
890 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin; | 933 NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin; |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 // If a "hover open" is pending when the bookmark bar folder is | 1304 // If a "hover open" is pending when the bookmark bar folder is |
1262 // closed, be sure it gets cancelled. | 1305 // closed, be sure it gets cancelled. |
1263 [NSObject cancelPreviousPerformRequestsWithTarget:self]; | 1306 [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
1264 | 1307 |
1265 [self endScroll]; // Just in case we were scrolling. | 1308 [self endScroll]; // Just in case we were scrolling. |
1266 [barController_ childFolderWillClose:self]; | 1309 [barController_ childFolderWillClose:self]; |
1267 [self closeBookmarkFolder:self]; | 1310 [self closeBookmarkFolder:self]; |
1268 [self autorelease]; | 1311 [self autorelease]; |
1269 } | 1312 } |
1270 | 1313 |
1271 - (int)indexOfButton:(BookmarkButton*)button { | |
1272 int index = [buttons_ indexOfObject:button]; | |
1273 return (index == NSNotFound) ? -1 : index; | |
1274 } | |
1275 | |
1276 - (BookmarkButton*)buttonAtIndex:(int)which { | |
1277 if (which < 0 || which >= [self buttonCount]) | |
1278 return nil; | |
1279 return [buttons_ objectAtIndex:which]; | |
1280 } | |
1281 | |
1282 #pragma mark BookmarkButtonDelegate Protocol | 1314 #pragma mark BookmarkButtonDelegate Protocol |
1283 | 1315 |
1284 - (void)fillPasteboard:(NSPasteboard*)pboard | 1316 - (void)fillPasteboard:(NSPasteboard*)pboard |
1285 forDragOfButton:(BookmarkButton*)button { | 1317 forDragOfButton:(BookmarkButton*)button { |
1286 [[self folderTarget] fillPasteboard:pboard forDragOfButton:button]; | 1318 [[self folderTarget] fillPasteboard:pboard forDragOfButton:button]; |
1287 | 1319 |
1288 // Close our folder menu and submenus since we know we're going to be dragged. | 1320 // Close our folder menu and submenus since we know we're going to be dragged. |
1289 [self closeBookmarkFolder:self]; | 1321 [self closeBookmarkFolder:self]; |
1290 } | 1322 } |
1291 | 1323 |
(...skipping 16 matching lines...) Expand all Loading... |
1308 [self performSelector:@selector(openBookmarkFolderFromButtonAndCloseOldOne:) | 1340 [self performSelector:@selector(openBookmarkFolderFromButtonAndCloseOldOne:) |
1309 withObject:sender | 1341 withObject:sender |
1310 afterDelay:bookmarks::kHoverOpenDelay | 1342 afterDelay:bookmarks::kHoverOpenDelay |
1311 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; | 1343 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; |
1312 } | 1344 } |
1313 | 1345 |
1314 // Called from the BookmarkButton | 1346 // Called from the BookmarkButton |
1315 - (void)mouseExitedButton:(id)sender event:(NSEvent*)event { | 1347 - (void)mouseExitedButton:(id)sender event:(NSEvent*)event { |
1316 if (buttonThatMouseIsIn_ == sender) | 1348 if (buttonThatMouseIsIn_ == sender) |
1317 buttonThatMouseIsIn_ = nil; | 1349 buttonThatMouseIsIn_ = nil; |
| 1350 [self setSelectedButtonByIndex:-1]; |
1318 | 1351 |
1319 // Stop any timer about opening a new hover-open folder. | 1352 // Stop any timer about opening a new hover-open folder. |
1320 | 1353 |
1321 // Since a performSelector:withDelay: on self retains self, it is | 1354 // Since a performSelector:withDelay: on self retains self, it is |
1322 // possible that a cancelPreviousPerformRequestsWithTarget: reduces | 1355 // possible that a cancelPreviousPerformRequestsWithTarget: reduces |
1323 // the refcount to 0, releasing us. That's a bad thing to do while | 1356 // the refcount to 0, releasing us. That's a bad thing to do while |
1324 // this object (or others it may own) is in the event chain. Thus | 1357 // this object (or others it may own) is in the event chain. Thus |
1325 // we have a retain/autorelease. | 1358 // we have a retain/autorelease. |
1326 [self retain]; | 1359 [self retain]; |
1327 [NSObject cancelPreviousPerformRequestsWithTarget:self]; | 1360 [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 | 1532 |
1500 [self performOneScroll:delta]; | 1533 [self performOneScroll:delta]; |
1501 } | 1534 } |
1502 | 1535 |
1503 // All changes to selectedness of buttons (aka fake menu items) ends up | 1536 // All changes to selectedness of buttons (aka fake menu items) ends up |
1504 // calling this method to actually flip the state of items. | 1537 // calling this method to actually flip the state of items. |
1505 // Needs to handle -1 as the invalid index (when nothing is selected) and | 1538 // Needs to handle -1 as the invalid index (when nothing is selected) and |
1506 // greater than range values too. | 1539 // greater than range values too. |
1507 - (void)setStateOfButtonByIndex:(int)index | 1540 - (void)setStateOfButtonByIndex:(int)index |
1508 state:(bool)state { | 1541 state:(bool)state { |
1509 if (index < 0 || index > ([self buttonCount] -1)) | 1542 if (index >= 0 && index < [self buttonCount]) |
1510 return; | 1543 [[buttons_ objectAtIndex:index] highlight:state]; |
1511 | |
1512 [[buttons_ objectAtIndex:index] highlight:state]; | |
1513 } | 1544 } |
1514 | 1545 |
1515 // Selects the required button and deselects the previously selected one. | 1546 // Selects the required button and deselects the previously selected one. |
1516 // An index of -1 means no selection. | 1547 // An index of -1 means no selection. |
1517 - (void)setSelectedButtonByIndex:(int)index { | 1548 - (void)setSelectedButtonByIndex:(int)index { |
1518 if (index == selectedIndex_) | 1549 if (index == selectedIndex_) |
1519 return; | 1550 return; |
1520 | 1551 |
1521 [self setStateOfButtonByIndex:selectedIndex_ state:NO]; | 1552 [self setStateOfButtonByIndex:selectedIndex_ state:NO]; |
1522 [self setStateOfButtonByIndex:index state:YES]; | 1553 [self setStateOfButtonByIndex:index state:YES]; |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 | 1986 |
1956 - (void)setIgnoreAnimations:(BOOL)ignore { | 1987 - (void)setIgnoreAnimations:(BOOL)ignore { |
1957 ignoreAnimations_ = ignore; | 1988 ignoreAnimations_ = ignore; |
1958 } | 1989 } |
1959 | 1990 |
1960 - (BookmarkButton*)buttonThatMouseIsIn { | 1991 - (BookmarkButton*)buttonThatMouseIsIn { |
1961 return buttonThatMouseIsIn_; | 1992 return buttonThatMouseIsIn_; |
1962 } | 1993 } |
1963 | 1994 |
1964 @end // BookmarkBarFolderController | 1995 @end // BookmarkBarFolderController |
OLD | NEW |