1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/sys_string_conversions.h"
#include "base/time/time.h"
#include "base/types/cxx23_to_underlying.h"
#include "chrome/app/vector_icons/vector_icons.h"
#import "chrome/browser/ui/autofill/autofill_popup_controller.h"
#include "components/autofill/core/browser/filling/filling_product.h"
#include "components/autofill/core/browser/suggestions/suggestion.h"
#include "components/autofill/core/browser/suggestions/suggestion_type.h"
#include "components/autofill/core/browser/ui/autofill_resource_utils.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/grit/components_scaled_resources.h"
#import "ui/base/cocoa/touch_bar_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia_util_mac.h"
#include "ui/gfx/paint_vector_icon.h"
namespace {
// Touch bar identifier.
NSString* const kCreditCardAutofillTouchBarId = @"credit-card-autofill";
// Touch bar items identifiers.
NSString* const kCreditCardTouchId = @"CREDIT-CARD";
NSString* const kCreditCardItemsTouchId = @"CREDIT-CARD-ITEMS";
// Maximum number of autofill items that can appear on the touch bar.
constexpr int maxTouchBarItems = 3;
// Returns the credit card image.
NSImage* GetCreditCardTouchBarImage(int iconId) {
if (iconId < 1) {
return nil;
}
// If it's a generic card image, use the vector icon instead.
if (iconId == IDR_AUTOFILL_CC_GENERIC) {
return NSImageFromImageSkia(
gfx::CreateVectorIcon(kCreditCardIcon, 16, SK_ColorWHITE));
}
return ui::ResourceBundle::GetSharedInstance()
.GetNativeImageNamed(iconId)
.AsNSImage();
}
} // namespace
@interface CreditCardAutofillTouchBarController ()
- (NSColor*)touchBarSubtextColor;
@end
@implementation CreditCardAutofillTouchBarController {
raw_ptr<autofill::AutofillPopupController> _controller; // weak
bool _is_credit_card_popup;
}
- (instancetype)initWithController:
(autofill::AutofillPopupController*)controller {
if ((self = [super init])) {
_controller = controller;
_is_credit_card_popup = (_controller->GetMainFillingProduct() ==
autofill::FillingProduct::kCreditCard);
}
return self;
}
- (NSTouchBar*)makeTouchBar {
if (!_controller->GetLineCount() || !_is_credit_card_popup) {
return nil;
}
NSTouchBar* touchBar = [[NSTouchBar alloc] init];
[touchBar setCustomizationIdentifier:ui::GetTouchBarId(
kCreditCardAutofillTouchBarId)];
touchBar.delegate = self;
[touchBar setDefaultItemIdentifiers:@[ kCreditCardItemsTouchId ]];
return touchBar;
}
- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
if (![identifier hasSuffix:kCreditCardItemsTouchId]) {
return nil;
}
NSMutableArray* creditCardItems = [NSMutableArray array];
for (int i = 0; i < _controller->GetLineCount() && i < maxTouchBarItems;
i++) {
const autofill::Suggestion& suggestion = _controller->GetSuggestionAt(i);
if (suggestion.type != autofill::SuggestionType::kAutocompleteEntry &&
suggestion.type != autofill::SuggestionType::kAddressEntry &&
suggestion.type != autofill::SuggestionType::kCreditCardEntry) {
continue;
}
NSString* cardIdentifier = [NSString
stringWithFormat:@"%@-%i",
ui::GetTouchBarItemId(kCreditCardAutofillTouchBarId,
kCreditCardTouchId),
i];
NSCustomTouchBarItem* item =
[[NSCustomTouchBarItem alloc] initWithIdentifier:cardIdentifier];
[item setView:[self createCreditCardButtonAtRow:i]];
[creditCardItems addObject:item];
}
return [NSGroupTouchBarItem groupItemWithIdentifier:identifier
items:creditCardItems];
}
- (NSColor*)touchBarSubtextColor {
return [NSColor colorWithCalibratedRed:206.0 / 255.0
green:206.0 / 255.0
blue:206.0 / 255.0
alpha:1.0];
}
- (NSButton*)createCreditCardButtonAtRow:(int)row {
const autofill::Suggestion& suggestion = _controller->GetSuggestionAt(row);
NSString* label = base::SysUTF16ToNSString(suggestion.main_text.value);
NSString* subtext = nil;
std::vector<std::vector<autofill::Suggestion::Text>> suggestion_labels =
suggestion.labels;
if (!suggestion_labels.empty()) {
CHECK_GT(suggestion_labels.size(), 0U);
CHECK_GT(suggestion_labels[0].size(), 0U);
subtext =
base::SysUTF16ToNSString(std::move(suggestion_labels[0][0].value));
}
// Create the button title based on the text direction.
NSString* buttonTitle =
[subtext length] ? [NSString stringWithFormat:@"%@ %@", label, subtext]
: label;
// Create the button.
NSImage* cardIconImage =
GetCreditCardTouchBarImage(autofill::GetIconResourceID(suggestion.icon));
NSButton* button = nil;
if (cardIconImage) {
button = [NSButton buttonWithTitle:buttonTitle
image:cardIconImage
target:self
action:@selector(acceptCreditCard:)];
button.imageHugsTitle = YES;
button.imagePosition = base::i18n::IsRTL() ? NSImageLeft : NSImageRight;
} else {
button = [NSButton buttonWithTitle:buttonTitle
target:self
action:@selector(acceptCreditCard:)];
}
// Apply text attributes to the button so that the subtext will appear
// smaller and lighter than the rest of the title.
NSMutableAttributedString* attributedString =
[button.attributedTitle mutableCopy];
NSFont* subtextFont =
[NSFontManager.sharedFontManager convertFont:button.font
toSize:button.font.pointSize - 1];
NSRange labelRange = NSMakeRange(0, label.length);
NSRange subtextRange =
NSMakeRange(buttonTitle.length - subtext.length, subtext.length);
[attributedString addAttribute:NSForegroundColorAttributeName
value:NSColor.whiteColor
range:labelRange];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[self touchBarSubtextColor]
range:subtextRange];
[attributedString addAttribute:NSFontAttributeName
value:subtextFont
range:subtextRange];
button.attributedTitle = attributedString;
// The tag is used to store the suggestion index.
button.tag = row;
return button;
}
- (void)acceptCreditCard:(id)sender {
_controller->AcceptSuggestion([sender tag]);
}
- (void)setIsCreditCardPopup:(bool)is_credit_card_popup {
_is_credit_card_popup = is_credit_card_popup;
}
@end
|