Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm

Issue 6889025: Mac. Ensure no more than one visibly selected item in each bookmark folder menu. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm ('k') | chrome/browser/ui/cocoa/gradient_button_cell.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698