summaryrefslogtreecommitdiffstats
path: root/ios/chrome/browser/autofill/form_suggestion_view.mm
blob: 4ac0467c2240cce5bd7f1c05c823db06089a75c1 (plain)
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
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ios/chrome/browser/autofill/form_suggestion_view.h"

#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsobject.h"
#import "ios/chrome/browser/autofill/form_suggestion_label.h"
#import "ios/chrome/browser/autofill/form_suggestion_view_client.h"

namespace {

// Vertical margin between suggestions and the edge of the suggestion content
// frame.
const CGFloat kSuggestionVerticalMargin = 4;

// Horizontal margin around suggestions (i.e. between suggestions, and between
// the end suggestions and the suggestion content frame).
const CGFloat kSuggestionHorizontalMargin = 2;

}  // namespace

@implementation FormSuggestionView {
  // The FormSuggestions that are displayed by this view.
  base::scoped_nsobject<NSArray> _suggestions;
}

- (instancetype)initWithFrame:(CGRect)frame
                       client:(id<FormSuggestionViewClient>)client
                  suggestions:(NSArray*)suggestions {
  self = [super initWithFrame:frame];
  if (self) {
    _suggestions.reset([suggestions copy]);

    self.showsVerticalScrollIndicator = NO;
    self.showsHorizontalScrollIndicator = NO;
    self.bounces = NO;
    self.canCancelContentTouches = YES;

    // Total height occupied by the label content, padding, border and margin.
    const CGFloat labelHeight =
        CGRectGetHeight(frame) - kSuggestionVerticalMargin * 2;

    BOOL isRTL = base::i18n::IsRTL();

    NSUInteger suggestionCount = [_suggestions count];
    // References to labels. These references are used to adjust the labels'
    // positions if they don't take up the whole suggestion view area for RTL.
    base::scoped_nsobject<NSMutableArray> labels(
        [[NSMutableArray alloc] initWithCapacity:suggestionCount]);
    __block CGFloat currentX = kSuggestionHorizontalMargin;
    void (^setupBlock)(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) =
        ^(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) {
          // FormSuggestionLabel will adjust the width, so here 0 is used for
          // the width.
          CGRect proposedFrame =
              CGRectMake(currentX, kSuggestionVerticalMargin, 0, labelHeight);
          base::scoped_nsobject<UIView> label(
              [[FormSuggestionLabel alloc] initWithSuggestion:suggestion
                                                proposedFrame:proposedFrame
                                                       client:client]);
          [self addSubview:label];
          [labels addObject:label];
          currentX +=
              CGRectGetWidth([label frame]) + kSuggestionHorizontalMargin;
        };
    [_suggestions enumerateObjectsWithOptions:(isRTL ? NSEnumerationReverse : 0)
                                   usingBlock:setupBlock];

    if (isRTL) {
      if (currentX < CGRectGetWidth(frame)) {
        self.contentSize = frame.size;
        // Offsets labels for right alignment.
        CGFloat offset = CGRectGetWidth(frame) - currentX;
        for (UIView* label in labels.get()) {
          label.frame = CGRectOffset(label.frame, offset, 0);
        }
      } else {
        self.contentSize = CGSizeMake(currentX, CGRectGetHeight(frame));
        // Sets the visible rectangle so suggestions at the right end are
        // initially visible.
        CGRect initRect = {{currentX - CGRectGetWidth(frame), 0}, frame.size};
        [self scrollRectToVisible:initRect animated:NO];
      }
    } else {
      self.contentSize = CGSizeMake(currentX, CGRectGetHeight(frame));
    }
  }
  return self;
}

- (NSArray*)suggestions {
  return _suggestions.get();
}

@end