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
|