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

Side by Side Diff: chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.mm

Issue 1931043002: Remove requestAutocomplete (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "chrome/browser/ui/cocoa/autofill/autofill_suggestion_container.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 #include "base/logging.h"
11 #include "base/mac/scoped_nsobject.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
14 #include "chrome/browser/ui/chrome_style.h"
15 #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
16 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
17 #include "skia/ext/skia_utils_mac.h"
18
19 namespace {
20
21 // Horizontal padding between text and other elements (in pixels).
22 const int kAroundTextPadding = 4;
23
24 // Padding at the top of suggestions.
25 const CGFloat kTopPadding = 10;
26
27 // Indicates infinite size in either vertical or horizontal direction.
28 // Technically, CGFLOAT_MAX should do. Practically, it runs into several issues.
29 // #1) Many computations on Retina devices overflow with that value.
30 // #2) In this particular use case, it results in the message
31 // "CGAffineTransformInvert: singular matrix."
32 const CGFloat kInfiniteSize = 1.0e6;
33
34 // A line fragment padding that creates the same visual look as text layout in
35 // an NSTextField does. (Which UX feedback was based on)
36 const CGFloat kLineFragmentPadding = 2.0;
37
38 // Padding added on top of the label so its first line looks centered with
39 // respect to the input field. Only added when the input field is showing.
40 const CGFloat kLabelWithInputTopPadding = 5.0;
41
42 }
43
44 // An attachment cell for a single icon - takes care of proper alignment of
45 // text and icon.
46 @interface IconAttachmentCell : NSTextAttachmentCell {
47 CGFloat baseline_; // The cell's baseline adjustment.
48 }
49
50 // Adjust the cell's baseline so that the lower edge of the image aligns with
51 // the longest descender, not the font baseline
52 - (void)adjustBaselineForFont:(NSFont*)font;
53
54 @end
55
56
57 @interface AutofillSuggestionView : NSView {
58 @private
59 // The main input field - only view not ignoring mouse events.
60 NSView* inputField_;
61 }
62
63 @property (assign, nonatomic) NSView* inputField;
64
65 @end
66
67
68 // The suggestion container should ignore any mouse events unless they occur
69 // within the bounds of an editable field.
70 @implementation AutofillSuggestionView
71
72 @synthesize inputField = inputField_;
73
74 - (NSView*)hitTest:(NSPoint)point {
75 NSView* hitView = [super hitTest:point];
76 if ([hitView isDescendantOf:inputField_])
77 return hitView;
78
79 return nil;
80 }
81
82 @end
83
84
85 @implementation IconAttachmentCell
86
87 - (NSPoint)cellBaselineOffset {
88 return NSMakePoint(0.0, baseline_);
89 }
90
91 // Ensure proper padding between text and icon.
92 - (NSSize)cellSize {
93 NSSize size = [super cellSize];
94 size.width += kAroundTextPadding;
95 return size;
96 }
97
98 // drawWithFrame: needs to be overridden to left-align the image. Default
99 // rendering centers images in the cell's frame.
100 - (void)drawWithFrame:(NSRect)frame inView:(NSView*)view {
101 frame.size.width -= kAroundTextPadding;
102 [super drawWithFrame:frame inView:view];
103 }
104
105 - (void)adjustBaselineForFont:(NSFont*)font {
106 CGFloat lineHeight = [font ascender];
107 baseline_ = std::floor((lineHeight - [[self image] size].height) / 2.0);
108 }
109
110 @end
111
112
113 @interface AutofillSuggestionContainer (Private)
114
115 // Set the main suggestion text and the corresponding |icon|.
116 // Attempts to wrap the text if |wrapText| is set.
117 - (void)setSuggestionText:(NSString*)line
118 icon:(NSImage*)icon
119 wrapText:(BOOL)wrapText;
120
121 @end
122
123
124 @implementation AutofillSuggestionContainer
125
126 - (AutofillTextField*)inputField {
127 return inputField_.get();
128 }
129
130 - (NSTextField*)makeDetailSectionLabel:(NSString*)labelText {
131 base::scoped_nsobject<NSTextField> label([[NSTextField alloc] init]);
132 [label setFont:
133 [[NSFontManager sharedFontManager] convertFont:[label font]
134 toHaveTrait:NSBoldFontMask]];
135 [label setStringValue:labelText];
136 [label setEditable:NO];
137 [label setBordered:NO];
138 [label sizeToFit];
139 return label.autorelease();
140 }
141
142 - (void)loadView {
143 label_.reset([[NSTextView alloc] initWithFrame:NSZeroRect]);
144 [[label_ textContainer] setLineFragmentPadding:kLineFragmentPadding];
145 [label_ setEditable:NO];
146 [label_ setSelectable:NO];
147 [label_ setDrawsBackground:NO];
148
149 base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
150 [[NSMutableParagraphStyle alloc] init]);
151 [paragraphStyle setLineSpacing:0.5 * [[label_ font] pointSize]];
152 [label_ setDefaultParagraphStyle:paragraphStyle];
153
154 inputField_.reset([[AutofillTextField alloc] initWithFrame:NSZeroRect]);
155 [inputField_ setHidden:YES];
156
157 spacer_.reset([[NSBox alloc] initWithFrame:NSZeroRect]);
158 [spacer_ setBoxType:NSBoxSeparator];
159 [spacer_ setBorderType:NSLineBorder];
160
161 base::scoped_nsobject<AutofillSuggestionView> view(
162 [[AutofillSuggestionView alloc] initWithFrame:NSZeroRect]);
163 [view setSubviews:
164 @[ label_, inputField_, spacer_ ]];
165 [view setInputField:inputField_];
166 [self setView:view];
167 }
168
169 - (void)setSuggestionText:(NSString*)line
170 icon:(NSImage*)icon
171 wrapText:(BOOL)wrapText {
172 [label_ setString:@""];
173
174 if ([icon size].width) {
175 base::scoped_nsobject<IconAttachmentCell> cell(
176 [[IconAttachmentCell alloc] initImageCell:icon]);
177 base::scoped_nsobject<NSTextAttachment> attachment(
178 [[NSTextAttachment alloc] init]);
179 [cell adjustBaselineForFont:[NSFont controlContentFontOfSize:0]];
180 [cell setAlignment:NSLeftTextAlignment];
181 [attachment setAttachmentCell:cell];
182 [[label_ textStorage] setAttributedString:
183 [NSAttributedString attributedStringWithAttachment:attachment]];
184 }
185
186 NSDictionary* attributes = @{
187 NSParagraphStyleAttributeName : [label_ defaultParagraphStyle],
188 NSCursorAttributeName : [NSCursor arrowCursor],
189 NSFontAttributeName : [NSFont controlContentFontOfSize:0]
190 };
191 base::scoped_nsobject<NSAttributedString> str1(
192 [[NSAttributedString alloc] initWithString:line
193 attributes:attributes]);
194 [[label_ textStorage] appendAttributedString:str1];
195
196 [label_ setVerticallyResizable:YES];
197 [label_ setHorizontallyResizable:!wrapText];
198 if (wrapText) {
199 CGFloat availableWidth =
200 4 * autofill::kFieldWidth - [inputField_ frame].size.width;
201 [label_ setFrameSize:NSMakeSize(availableWidth, kInfiniteSize)];
202 } else {
203 [label_ setFrameSize:NSMakeSize(kInfiniteSize, kInfiniteSize)];
204 }
205 [[label_ layoutManager] ensureLayoutForTextContainer:[label_ textContainer]];
206 [label_ sizeToFit];
207 }
208
209 - (void)
210 setSuggestionWithVerticallyCompactText:(NSString*)verticallyCompactText
211 horizontallyCompactText:(NSString*)horizontallyCompactText
212 icon:(NSImage*)icon
213 maxWidth:(CGFloat)maxWidth {
214 // Prefer the vertically compact text when it fits. If it doesn't fit, fall
215 // back to the horizontally compact text.
216 [self setSuggestionText:verticallyCompactText icon:icon wrapText:NO];
217 if ([self preferredSize].width > maxWidth)
218 [self setSuggestionText:horizontallyCompactText icon:icon wrapText:YES];
219 }
220
221
222 - (void)showInputField:(NSString*)text withIcon:(NSImage*)icon {
223 [[inputField_ cell] setPlaceholderString:text];
224 [[inputField_ cell] setIcon:icon];
225 [inputField_ setHidden:NO];
226 [inputField_ sizeToFit];
227
228 // Enforce fixed width.
229 NSSize frameSize = NSMakeSize(autofill::kFieldWidth,
230 NSHeight([inputField_ frame]));
231 [inputField_ setFrameSize:frameSize];
232 }
233
234
235 - (NSSize)preferredSize {
236 NSSize size = [label_ bounds].size;
237
238 // Final inputField_ sizing/spacing depends on a TODO(estade) in Views code.
239 if (![inputField_ isHidden]) {
240 size.height = std::max(size.height + kLabelWithInputTopPadding,
241 NSHeight([inputField_ frame]));
242 size.width += NSWidth([inputField_ frame]) + kAroundTextPadding;
243 }
244
245 size.height += kTopPadding;
246
247 return size;
248 }
249
250 - (void)performLayout {
251 NSRect bounds = [[self view] bounds];
252 NSSize preferredContainerSize = [self preferredSize];
253 // width is externally determined.
254 preferredContainerSize.width = NSWidth(bounds);
255
256 NSRect spacerFrame = NSMakeRect(0, preferredContainerSize.height - 1,
257 preferredContainerSize.width, 1);
258
259 NSRect labelFrame = [label_ bounds];
260 labelFrame.origin.x = NSMinX(bounds);
261 labelFrame.origin.y = NSMaxY(bounds) - NSHeight(labelFrame) - kTopPadding;
262
263 // Position input field - top is aligned to top of label field.
264 if (![inputField_ isHidden]) {
265 NSRect inputFieldFrame = [inputField_ frame];
266 inputFieldFrame.origin.x = NSMaxX(bounds) - NSWidth(inputFieldFrame);
267 inputFieldFrame.origin.y = NSMaxY(labelFrame) - NSHeight(inputFieldFrame);
268 [inputField_ setFrameOrigin:inputFieldFrame.origin];
269
270 // Vertically center the first line of the label with respect to the input
271 // field.
272 labelFrame.origin.y -= kLabelWithInputTopPadding;
273
274 // Due to fixed width, fields are guaranteed to not overlap.
275 DCHECK_LE(NSMaxX(labelFrame), NSMinX(inputFieldFrame));
276 }
277
278 [spacer_ setFrame:spacerFrame];
279 [label_ setFrame:labelFrame];
280 [[self view] setFrameSize:preferredContainerSize];
281 }
282
283 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698