OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h" | 7 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h" |
8 | 8 |
9 #include "base/mac/bundle_locations.h" | 9 #include "base/mac/bundle_locations.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 withController:(ProfileChooserController*)controller; | 448 withController:(ProfileChooserController*)controller; |
449 | 449 |
450 // Called when the "Change" button is clicked. | 450 // Called when the "Change" button is clicked. |
451 - (void)editPhoto:(id)sender; | 451 - (void)editPhoto:(id)sender; |
452 | 452 |
453 // When hovering over the profile photo, show the "Change" button. | 453 // When hovering over the profile photo, show the "Change" button. |
454 - (void)mouseEntered:(NSEvent*)event; | 454 - (void)mouseEntered:(NSEvent*)event; |
455 | 455 |
456 // When hovering away from the profile photo, hide the "Change" button. | 456 // When hovering away from the profile photo, hide the "Change" button. |
457 - (void)mouseExited:(NSEvent*)event; | 457 - (void)mouseExited:(NSEvent*)event; |
458 | |
459 - (BOOL)acceptsFirstResponder; | |
460 - (BOOL)canBecomeKeyView; | |
461 - (BOOL)accessibilityIsIgnored; | |
462 - (NSArray*)accessibilityActionNames; | |
463 - (void)accessibilityPerformAction:(NSString*)action; | |
groby-ooo-7-16
2014/08/15 00:38:35
No need to declare any of them - they're all imple
noms (inactive)
2014/08/15 19:26:47
Argh, sorry. I never know when to declare and when
groby-ooo-7-16
2014/08/15 19:52:07
This is one of the few places ObjC pretends to not
| |
458 @end | 464 @end |
459 | 465 |
460 @interface EditableProfilePhoto (Private) | 466 @interface EditableProfilePhoto (Private) |
461 // Create the "Change" avatar photo button. | 467 // Create the "Change" avatar photo button. |
462 - (TransparentBackgroundButton*)changePhotoButtonWithRect:(NSRect)rect; | 468 - (TransparentBackgroundButton*)changePhotoButtonWithRect:(NSRect)rect; |
463 @end | 469 @end |
464 | 470 |
465 @implementation EditableProfilePhoto | 471 @implementation EditableProfilePhoto |
466 - (id)initWithFrame:(NSRect)frameRect | 472 - (id)initWithFrame:(NSRect)frameRect |
467 avatarMenu:(AvatarMenu*)avatarMenu | 473 avatarMenu:(AvatarMenu*)avatarMenu |
(...skipping 15 matching lines...) Expand all Loading... | |
483 [self addTrackingArea:trackingArea_.get()]; | 489 [self addTrackingArea:trackingArea_.get()]; |
484 | 490 |
485 NSRect bounds = NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide); | 491 NSRect bounds = NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide); |
486 if (editingAllowed) { | 492 if (editingAllowed) { |
487 changePhotoButton_.reset([self changePhotoButtonWithRect:bounds]); | 493 changePhotoButton_.reset([self changePhotoButtonWithRect:bounds]); |
488 [self addSubview:changePhotoButton_]; | 494 [self addSubview:changePhotoButton_]; |
489 | 495 |
490 // Hide the button until the image is hovered over. | 496 // Hide the button until the image is hovered over. |
491 [changePhotoButton_ setHidden:YES]; | 497 [changePhotoButton_ setHidden:YES]; |
492 } | 498 } |
499 | |
500 // Set the image cell's accessibility strings to be the same as the | |
501 // button's strings. | |
502 [[self cell] accessibilitySetOverrideValue:l10n_util::GetNSString( | |
503 editingAllowed ? | |
504 IDS_PROFILES_NEW_AVATAR_MENU_CHANGE_PHOTO_ACCESSIBLE_NAME : | |
505 IDS_PROFILES_NEW_AVATAR_MENU_PHOTO_ACCESSIBLE_NAME) | |
506 forAttribute:NSAccessibilityTitleAttribute]; | |
507 [[self cell] accessibilitySetOverrideValue: | |
508 editingAllowed ? NSAccessibilityButtonRole : NSAccessibilityImageRole | |
509 forAttribute:NSAccessibilityRoleAttribute]; | |
510 [[self cell] accessibilitySetOverrideValue: | |
511 NSAccessibilityRoleDescription(NSAccessibilityButtonRole, nil) | |
512 forAttribute:NSAccessibilityRoleDescriptionAttribute]; | |
513 | |
514 // The button and the cell should read the same thing. | |
515 [self accessibilitySetOverrideValue:l10n_util::GetNSString( | |
516 editingAllowed ? | |
517 IDS_PROFILES_NEW_AVATAR_MENU_CHANGE_PHOTO_ACCESSIBLE_NAME : | |
518 IDS_PROFILES_NEW_AVATAR_MENU_PHOTO_ACCESSIBLE_NAME) | |
519 forAttribute:NSAccessibilityTitleAttribute]; | |
520 [self accessibilitySetOverrideValue:NSAccessibilityButtonRole | |
521 forAttribute:NSAccessibilityRoleAttribute]; | |
522 [self accessibilitySetOverrideValue: | |
523 NSAccessibilityRoleDescription(NSAccessibilityButtonRole, nil) | |
524 forAttribute:NSAccessibilityRoleDescriptionAttribute]; | |
493 } | 525 } |
494 return self; | 526 return self; |
495 } | 527 } |
496 | 528 |
497 - (void)drawRect:(NSRect)dirtyRect { | 529 - (void)drawRect:(NSRect)dirtyRect { |
498 NSRect bounds = [self bounds]; | 530 NSRect bounds = [self bounds]; |
499 | 531 |
500 // Display the profile picture as a circle. | 532 // Display the profile picture as a circle. |
501 NSBezierPath* path = [NSBezierPath bezierPathWithOvalInRect:bounds]; | 533 NSBezierPath* path = [NSBezierPath bezierPathWithOvalInRect:bounds]; |
502 [path addClip]; | 534 [path addClip]; |
(...skipping 11 matching lines...) Expand all Loading... | |
514 } | 546 } |
515 | 547 |
516 - (void)mouseEntered:(NSEvent*)event { | 548 - (void)mouseEntered:(NSEvent*)event { |
517 [changePhotoButton_ setHidden:NO]; | 549 [changePhotoButton_ setHidden:NO]; |
518 } | 550 } |
519 | 551 |
520 - (void)mouseExited:(NSEvent*)event { | 552 - (void)mouseExited:(NSEvent*)event { |
521 [changePhotoButton_ setHidden:YES]; | 553 [changePhotoButton_ setHidden:YES]; |
522 } | 554 } |
523 | 555 |
556 // Make sure the element is focusable for accessibility. | |
557 - (BOOL)canBecomeKeyView { | |
558 return YES; | |
559 } | |
560 | |
561 - (BOOL)acceptsFirstResponder { | |
562 return YES; | |
563 } | |
564 | |
565 - (BOOL)accessibilityIsIgnored { | |
566 return NO; | |
567 } | |
568 | |
569 - (NSArray*)accessibilityActionNames { | |
570 NSArray* parentActions = [super accessibilityActionNames]; | |
571 return [parentActions arrayByAddingObject:NSAccessibilityPressAction]; | |
572 } | |
573 | |
574 - (void)accessibilityPerformAction:(NSString*)action { | |
575 if ([action isEqualToString:NSAccessibilityPressAction]) { | |
576 avatarMenu_->EditProfile(avatarMenu_->GetActiveProfileIndex()); | |
577 } | |
578 | |
579 [super accessibilityPerformAction:action]; | |
580 } | |
581 | |
524 - (TransparentBackgroundButton*)changePhotoButtonWithRect:(NSRect)rect { | 582 - (TransparentBackgroundButton*)changePhotoButtonWithRect:(NSRect)rect { |
525 TransparentBackgroundButton* button = | 583 TransparentBackgroundButton* button = |
526 [[TransparentBackgroundButton alloc] initWithFrame:rect]; | 584 [[TransparentBackgroundButton alloc] initWithFrame:rect]; |
527 [button setImage:ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 585 [button setImage:ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
528 IDR_ICON_PROFILES_EDIT_CAMERA).AsNSImage()]; | 586 IDR_ICON_PROFILES_EDIT_CAMERA).AsNSImage()]; |
529 [button setImagePosition:NSImageOnly]; | 587 [button setImagePosition:NSImageOnly]; |
530 [button setTarget:self]; | 588 [button setTarget:self]; |
531 [button setAction:@selector(editPhoto:)]; | 589 [button setAction:@selector(editPhoto:)]; |
532 return button; | 590 return button; |
533 } | 591 } |
(...skipping 12 matching lines...) Expand all Loading... | |
546 profileName:(NSString*)profileName | 604 profileName:(NSString*)profileName |
547 editingAllowed:(BOOL)editingAllowed | 605 editingAllowed:(BOOL)editingAllowed |
548 withController:(ProfileChooserController*)controller; | 606 withController:(ProfileChooserController*)controller; |
549 | 607 |
550 // Called when the button is clicked. | 608 // Called when the button is clicked. |
551 - (void)showEditableView:(id)sender; | 609 - (void)showEditableView:(id)sender; |
552 | 610 |
553 // Called when enter is pressed in the text field. | 611 // Called when enter is pressed in the text field. |
554 - (void)saveProfileName:(id)sender; | 612 - (void)saveProfileName:(id)sender; |
555 | 613 |
614 - (BOOL)acceptsFirstResponder; | |
615 | |
556 @end | 616 @end |
557 | 617 |
558 @implementation EditableProfileNameButton | 618 @implementation EditableProfileNameButton |
559 - (id)initWithFrame:(NSRect)frameRect | 619 - (id)initWithFrame:(NSRect)frameRect |
560 profile:(Profile*)profile | 620 profile:(Profile*)profile |
561 profileName:(NSString*)profileName | 621 profileName:(NSString*)profileName |
562 editingAllowed:(BOOL)editingAllowed | 622 editingAllowed:(BOOL)editingAllowed |
563 withController:(ProfileChooserController*)controller { | 623 withController:(ProfileChooserController*)controller { |
564 if ((self = [super initWithFrame:frameRect])) { | 624 if ((self = [super initWithFrame:frameRect])) { |
565 profile_ = profile; | 625 profile_ = profile; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 [[profileNameTextField_ cell] setLineBreakMode: | 666 [[profileNameTextField_ cell] setLineBreakMode: |
607 NSLineBreakByTruncatingTail]; | 667 NSLineBreakByTruncatingTail]; |
608 [self addSubview:profileNameTextField_]; | 668 [self addSubview:profileNameTextField_]; |
609 [profileNameTextField_ setTarget:self]; | 669 [profileNameTextField_ setTarget:self]; |
610 [profileNameTextField_ setAction:@selector(saveProfileName:)]; | 670 [profileNameTextField_ setAction:@selector(saveProfileName:)]; |
611 | 671 |
612 // Hide the textfield until the user clicks on the button. | 672 // Hide the textfield until the user clicks on the button. |
613 [profileNameTextField_ setHidden:YES]; | 673 [profileNameTextField_ setHidden:YES]; |
614 } | 674 } |
615 | 675 |
676 [[self cell] accessibilitySetOverrideValue:NSAccessibilityButtonRole | |
677 forAttribute:NSAccessibilityRoleAttribute]; | |
678 [[self cell] accessibilitySetOverrideValue: | |
679 NSAccessibilityRoleDescription(NSAccessibilityButtonRole, nil) | |
680 forAttribute:NSAccessibilityRoleDescriptionAttribute]; | |
681 | |
616 [self setBordered:NO]; | 682 [self setBordered:NO]; |
617 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]]; | 683 [self setFont:[NSFont labelFontOfSize:kTitleFontSize]]; |
618 [self setAlignment:NSCenterTextAlignment]; | 684 [self setAlignment:NSCenterTextAlignment]; |
619 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail]; | 685 [[self cell] setLineBreakMode:NSLineBreakByTruncatingTail]; |
620 [self setTitle:profileName]; | 686 [self setTitle:profileName]; |
621 } | 687 } |
622 return self; | 688 return self; |
623 } | 689 } |
624 | 690 |
625 - (void)saveProfileName:(id)sender { | 691 - (void)saveProfileName:(id)sender { |
626 NSString* text = [profileNameTextField_ stringValue]; | 692 NSString* text = [profileNameTextField_ stringValue]; |
627 // Empty profile names are not allowed, and are treated as a cancel. | 693 // Empty profile names are not allowed, and are treated as a cancel. |
628 if ([text length] > 0) { | 694 if ([text length] > 0) { |
629 profiles::UpdateProfileName(profile_, base::SysNSStringToUTF16(text)); | 695 profiles::UpdateProfileName(profile_, base::SysNSStringToUTF16(text)); |
630 [controller_ | 696 [controller_ |
631 postActionPerformed:ProfileMetrics::PROFILE_DESKTOP_MENU_EDIT_NAME]; | 697 postActionPerformed:ProfileMetrics::PROFILE_DESKTOP_MENU_EDIT_NAME]; |
632 [self setTitle:text]; | 698 [self setTitle:text]; |
633 } | 699 } |
634 [profileNameTextField_ setHidden:YES]; | 700 [profileNameTextField_ setHidden:YES]; |
635 } | 701 } |
636 | 702 |
637 - (void)showEditableView:(id)sender { | 703 - (void)showEditableView:(id)sender { |
638 [profileNameTextField_ setHidden:NO]; | 704 [profileNameTextField_ setHidden:NO]; |
639 [[self window] makeFirstResponder:profileNameTextField_]; | 705 [[self window] makeFirstResponder:profileNameTextField_]; |
640 } | 706 } |
641 | 707 |
708 - (BOOL)acceptsFirstResponder { | |
groby-ooo-7-16
2014/08/15 00:38:35
Technically, a control's -acceptsFirstResponder is
noms (inactive)
2014/08/15 19:26:47
No. I think I just hoped these would make regular
| |
709 return YES; | |
710 } | |
711 | |
642 @end | 712 @end |
643 | 713 |
644 // A custom button that allows for setting a background color when hovered over. | 714 // A custom button that allows for setting a background color when hovered over. |
645 @interface BackgroundColorHoverButton : HoverImageButton { | 715 @interface BackgroundColorHoverButton : HoverImageButton { |
646 @private | 716 @private |
647 base::scoped_nsobject<NSColor> backgroundColor_; | 717 base::scoped_nsobject<NSColor> backgroundColor_; |
648 base::scoped_nsobject<NSColor> hoverColor_; | 718 base::scoped_nsobject<NSColor> hoverColor_; |
649 } | 719 } |
650 @end | 720 @end |
651 | 721 |
(...skipping 27 matching lines...) Expand all Loading... | |
679 } | 749 } |
680 | 750 |
681 - (void)setHoverState:(HoverState)state { | 751 - (void)setHoverState:(HoverState)state { |
682 [super setHoverState:state]; | 752 [super setHoverState:state]; |
683 bool isHighlighted = ([self hoverState] != kHoverStateNone); | 753 bool isHighlighted = ([self hoverState] != kHoverStateNone); |
684 | 754 |
685 NSColor* backgroundColor = isHighlighted ? hoverColor_ : backgroundColor_; | 755 NSColor* backgroundColor = isHighlighted ? hoverColor_ : backgroundColor_; |
686 [[self cell] setBackgroundColor:backgroundColor]; | 756 [[self cell] setBackgroundColor:backgroundColor]; |
687 } | 757 } |
688 | 758 |
759 - (BOOL)acceptsFirstResponder { | |
760 return YES; | |
761 } | |
762 | |
689 @end | 763 @end |
690 | 764 |
691 // A custom view with the given background color. | 765 // A custom view with the given background color. |
692 @interface BackgroundColorView : NSView { | 766 @interface BackgroundColorView : NSView { |
693 @private | 767 @private |
694 base::scoped_nsobject<NSColor> backgroundColor_; | 768 base::scoped_nsobject<NSColor> backgroundColor_; |
695 } | 769 } |
696 @end | 770 @end |
697 | 771 |
698 @implementation BackgroundColorView | 772 @implementation BackgroundColorView |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
975 // If view mode is PROFILE_CHOOSER but there is an auth error, force | 1049 // If view mode is PROFILE_CHOOSER but there is an auth error, force |
976 // ACCOUNT_MANAGEMENT mode. | 1050 // ACCOUNT_MANAGEMENT mode. |
977 if (viewMode_ == profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER && | 1051 if (viewMode_ == profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER && |
978 HasAuthError(browser_->profile()) && | 1052 HasAuthError(browser_->profile()) && |
979 switches::IsEnableAccountConsistency() && | 1053 switches::IsEnableAccountConsistency() && |
980 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex()). | 1054 avatarMenu_->GetItemAt(avatarMenu_->GetActiveProfileIndex()). |
981 signed_in) { | 1055 signed_in) { |
982 viewMode_ = profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT; | 1056 viewMode_ = profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT; |
983 } | 1057 } |
984 | 1058 |
1059 [window accessibilitySetOverrideValue: | |
1060 l10n_util::GetNSString(IDS_PROFILES_NEW_AVATAR_MENU_ACCESSIBLE_NAME) | |
1061 forAttribute:NSAccessibilityTitleAttribute]; | |
1062 [window accessibilitySetOverrideValue: | |
1063 l10n_util::GetNSString(IDS_PROFILES_NEW_AVATAR_MENU_ACCESSIBLE_NAME) | |
1064 forAttribute:NSAccessibilityHelpAttribute]; | |
1065 | |
985 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; | 1066 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; |
986 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; | 1067 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; |
987 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()]; | 1068 [[self bubble] setBackgroundColor:GetDialogBackgroundColor()]; |
988 [self initMenuContentsWithView:viewMode_]; | 1069 [self initMenuContentsWithView:viewMode_]; |
989 } | 1070 } |
990 | 1071 |
991 return self; | 1072 return self; |
992 } | 1073 } |
993 | 1074 |
994 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay { | 1075 - (void)initMenuContentsWithView:(profiles::BubbleViewMode)viewToDisplay { |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1387 link = [self linkButtonWithTitle:email | 1468 link = [self linkButtonWithTitle:email |
1388 frameOrigin:rect.origin | 1469 frameOrigin:rect.origin |
1389 action:nil]; | 1470 action:nil]; |
1390 [link setImage:ui::ResourceBundle::GetSharedInstance(). | 1471 [link setImage:ui::ResourceBundle::GetSharedInstance(). |
1391 GetNativeImageNamed(IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR). | 1472 GetNativeImageNamed(IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR). |
1392 ToNSImage()]; | 1473 ToNSImage()]; |
1393 [link setImagePosition:NSImageRight]; | 1474 [link setImagePosition:NSImageRight]; |
1394 [link setTarget:self]; | 1475 [link setTarget:self]; |
1395 [link setAction:@selector(showAccountReauthenticationView:)]; | 1476 [link setAction:@selector(showAccountReauthenticationView:)]; |
1396 [link setTag:kPrimaryProfileTag]; | 1477 [link setTag:kPrimaryProfileTag]; |
1478 [[link cell] | |
1479 accessibilitySetOverrideValue:l10n_util::GetNSStringF( | |
1480 IDS_PROFILES_ACCOUNT_BUTTON_AUTH_ERROR_ACCESSIBLE_NAME, | |
1481 item.sync_state) | |
1482 forAttribute:NSAccessibilityTitleAttribute]; | |
1397 } else { | 1483 } else { |
1398 NSTextField* label = BuildLabel(email, rect.origin, nil); | 1484 NSTextField* label = BuildLabel(email, rect.origin, nil); |
1399 [label setAlignment:NSCenterTextAlignment]; | 1485 [label setAlignment:NSCenterTextAlignment]; |
1400 [label setFrame:rect]; | 1486 [label setFrame:rect]; |
1401 [container addSubview:label]; | 1487 [container addSubview:label]; |
1402 } | 1488 } |
1403 } | 1489 } |
1404 // -linkButtonWithTitle sizeToFit's the link, so re-stretch it so that it | 1490 // -linkButtonWithTitle sizeToFit's the link, so re-stretch it so that it |
1405 // can be centered correctly in the view. | 1491 // can be centered correctly in the view. |
1406 if (link) { | 1492 if (link) { |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1961 } | 2047 } |
1962 | 2048 |
1963 - (bool)shouldShowGoIncognito { | 2049 - (bool)shouldShowGoIncognito { |
1964 bool incognitoAvailable = | 2050 bool incognitoAvailable = |
1965 IncognitoModePrefs::GetAvailability(browser_->profile()->GetPrefs()) != | 2051 IncognitoModePrefs::GetAvailability(browser_->profile()->GetPrefs()) != |
1966 IncognitoModePrefs::DISABLED; | 2052 IncognitoModePrefs::DISABLED; |
1967 return incognitoAvailable && !browser_->profile()->IsGuestSession(); | 2053 return incognitoAvailable && !browser_->profile()->IsGuestSession(); |
1968 } | 2054 } |
1969 | 2055 |
1970 @end | 2056 @end |
OLD | NEW |