Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / ios / chrome / browser / autofill / form_suggestion_view.mm
blob4ac0467c2240cce5bd7f1c05c823db06089a75c1
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.
5 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
7 #include "base/i18n/rtl.h"
8 #include "base/mac/scoped_nsobject.h"
9 #import "ios/chrome/browser/autofill/form_suggestion_label.h"
10 #import "ios/chrome/browser/autofill/form_suggestion_view_client.h"
12 namespace {
14 // Vertical margin between suggestions and the edge of the suggestion content
15 // frame.
16 const CGFloat kSuggestionVerticalMargin = 4;
18 // Horizontal margin around suggestions (i.e. between suggestions, and between
19 // the end suggestions and the suggestion content frame).
20 const CGFloat kSuggestionHorizontalMargin = 2;
22 }  // namespace
24 @implementation FormSuggestionView {
25   // The FormSuggestions that are displayed by this view.
26   base::scoped_nsobject<NSArray> _suggestions;
29 - (instancetype)initWithFrame:(CGRect)frame
30                        client:(id<FormSuggestionViewClient>)client
31                   suggestions:(NSArray*)suggestions {
32   self = [super initWithFrame:frame];
33   if (self) {
34     _suggestions.reset([suggestions copy]);
36     self.showsVerticalScrollIndicator = NO;
37     self.showsHorizontalScrollIndicator = NO;
38     self.bounces = NO;
39     self.canCancelContentTouches = YES;
41     // Total height occupied by the label content, padding, border and margin.
42     const CGFloat labelHeight =
43         CGRectGetHeight(frame) - kSuggestionVerticalMargin * 2;
45     BOOL isRTL = base::i18n::IsRTL();
47     NSUInteger suggestionCount = [_suggestions count];
48     // References to labels. These references are used to adjust the labels'
49     // positions if they don't take up the whole suggestion view area for RTL.
50     base::scoped_nsobject<NSMutableArray> labels(
51         [[NSMutableArray alloc] initWithCapacity:suggestionCount]);
52     __block CGFloat currentX = kSuggestionHorizontalMargin;
53     void (^setupBlock)(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) =
54         ^(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) {
55           // FormSuggestionLabel will adjust the width, so here 0 is used for
56           // the width.
57           CGRect proposedFrame =
58               CGRectMake(currentX, kSuggestionVerticalMargin, 0, labelHeight);
59           base::scoped_nsobject<UIView> label(
60               [[FormSuggestionLabel alloc] initWithSuggestion:suggestion
61                                                 proposedFrame:proposedFrame
62                                                        client:client]);
63           [self addSubview:label];
64           [labels addObject:label];
65           currentX +=
66               CGRectGetWidth([label frame]) + kSuggestionHorizontalMargin;
67         };
68     [_suggestions enumerateObjectsWithOptions:(isRTL ? NSEnumerationReverse : 0)
69                                    usingBlock:setupBlock];
71     if (isRTL) {
72       if (currentX < CGRectGetWidth(frame)) {
73         self.contentSize = frame.size;
74         // Offsets labels for right alignment.
75         CGFloat offset = CGRectGetWidth(frame) - currentX;
76         for (UIView* label in labels.get()) {
77           label.frame = CGRectOffset(label.frame, offset, 0);
78         }
79       } else {
80         self.contentSize = CGSizeMake(currentX, CGRectGetHeight(frame));
81         // Sets the visible rectangle so suggestions at the right end are
82         // initially visible.
83         CGRect initRect = {{currentX - CGRectGetWidth(frame), 0}, frame.size};
84         [self scrollRectToVisible:initRect animated:NO];
85       }
86     } else {
87       self.contentSize = CGSizeMake(currentX, CGRectGetHeight(frame));
88     }
89   }
90   return self;
93 - (NSArray*)suggestions {
94   return _suggestions.get();
97 @end