1// Copyright 2017 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 "ios/chrome/search_widget_extension/search_action_view.h"
6
7#import <NotificationCenter/NotificationCenter.h>
8
9#include "base/check.h"
10#import "ios/chrome/common/ui/util/constraints_ui_util.h"
11#import "ios/chrome/search_widget_extension/search_widget_constants.h"
12
13#if !defined(__has_feature) || !__has_feature(objc_arc)
14#error "This file requires ARC support."
15#endif
16
17namespace {
18
19const CGFloat kActionButtonSize = 55;
20const CGFloat kIconSize = 35;
21
22}  // namespace
23
24@implementation SearchActionView
25
26- (instancetype)initWithActionTarget:(id)target
27                      actionSelector:(SEL)actionSelector
28                               title:(NSString*)title
29                           imageName:(NSString*)imageName {
30  DCHECK(target);
31  self = [super initWithFrame:CGRectZero];
32  if (self) {
33    self.translatesAutoresizingMaskIntoConstraints = NO;
34
35    UIVibrancyEffect* primaryEffect = nil;
36    UIVibrancyEffect* secondaryEffect = nil;
37    UIVibrancyEffect* iconBackgroundEffect = nil;
38    if (@available(iOS 13, *)) {
39      primaryEffect = [UIVibrancyEffect
40          widgetEffectForVibrancyStyle:UIVibrancyEffectStyleLabel];
41      secondaryEffect = [UIVibrancyEffect
42          widgetEffectForVibrancyStyle:UIVibrancyEffectStyleSecondaryLabel];
43      iconBackgroundEffect = [UIVibrancyEffect
44          widgetEffectForVibrancyStyle:UIVibrancyEffectStyleTertiaryFill];
45    }
46#if !defined(__IPHONE_13_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0
47    else {
48      primaryEffect = [UIVibrancyEffect widgetPrimaryVibrancyEffect];
49      secondaryEffect = [UIVibrancyEffect widgetSecondaryVibrancyEffect];
50      iconBackgroundEffect = [UIVibrancyEffect widgetSecondaryVibrancyEffect];
51    }
52#endif
53    DCHECK(primaryEffect);
54    DCHECK(secondaryEffect);
55    DCHECK(iconBackgroundEffect);
56
57    UIVisualEffectView* primaryEffectView =
58        [[UIVisualEffectView alloc] initWithEffect:primaryEffect];
59    UIVisualEffectView* secondaryEffectView =
60        [[UIVisualEffectView alloc] initWithEffect:secondaryEffect];
61    UIVisualEffectView* iconBackgroundEffectView =
62        [[UIVisualEffectView alloc] initWithEffect:iconBackgroundEffect];
63    for (UIVisualEffectView* effectView in @[
64           primaryEffectView, secondaryEffectView, iconBackgroundEffectView
65         ]) {
66      effectView.translatesAutoresizingMaskIntoConstraints = NO;
67      effectView.userInteractionEnabled = NO;
68    }
69
70    UIView* circleView = [[UIView alloc] initWithFrame:CGRectZero];
71    circleView.translatesAutoresizingMaskIntoConstraints = NO;
72    if (@available(iOS 13, *)) {
73      circleView.backgroundColor = UIColor.whiteColor;
74    } else {
75      circleView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05];
76    }
77    circleView.layer.cornerRadius = kActionButtonSize / 2;
78    [iconBackgroundEffectView.contentView addSubview:circleView];
79    AddSameConstraints(iconBackgroundEffectView.contentView, circleView);
80
81    UILabel* labelView = [[UILabel alloc] initWithFrame:CGRectZero];
82    labelView.translatesAutoresizingMaskIntoConstraints = NO;
83    labelView.text = title;
84    labelView.numberOfLines = 0;
85    labelView.textAlignment = NSTextAlignmentCenter;
86    labelView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2];
87    labelView.isAccessibilityElement = NO;
88    [labelView
89        setContentCompressionResistancePriority:UILayoutPriorityRequired
90                                        forAxis:UILayoutConstraintAxisVertical];
91    [secondaryEffectView.contentView addSubview:labelView];
92    AddSameConstraints(secondaryEffectView.contentView, labelView);
93
94    UIStackView* stack = [[UIStackView alloc] initWithArrangedSubviews:@[
95      iconBackgroundEffectView, secondaryEffectView
96    ]];
97    stack.axis = UILayoutConstraintAxisVertical;
98    stack.spacing = kIconSpacing;
99    stack.alignment = UIStackViewAlignmentCenter;
100    stack.translatesAutoresizingMaskIntoConstraints = NO;
101    stack.userInteractionEnabled = NO;
102    [self addSubview:stack];
103    AddSameConstraints(self, stack);
104
105    UIImage* iconImage = [UIImage imageNamed:imageName];
106    iconImage =
107        [iconImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
108    UIImageView* icon = [[UIImageView alloc] initWithImage:iconImage];
109    icon.translatesAutoresizingMaskIntoConstraints = NO;
110    [primaryEffectView.contentView addSubview:icon];
111    AddSameConstraints(primaryEffectView.contentView, icon);
112    [self addSubview:primaryEffectView];
113
114    [NSLayoutConstraint activateConstraints:@[
115      [circleView.widthAnchor constraintEqualToConstant:kActionButtonSize],
116      [circleView.heightAnchor constraintEqualToConstant:kActionButtonSize],
117      [icon.widthAnchor constraintEqualToConstant:kIconSize],
118      [icon.heightAnchor constraintEqualToConstant:kIconSize],
119      [icon.centerXAnchor constraintEqualToAnchor:circleView.centerXAnchor],
120      [icon.centerYAnchor constraintEqualToAnchor:circleView.centerYAnchor],
121    ]];
122
123    self.userInteractionEnabled = YES;
124    [self addTarget:target
125                  action:actionSelector
126        forControlEvents:UIControlEventTouchUpInside];
127    self.accessibilityLabel = title;
128
129    self.highlightableViews = @[ circleView, labelView, icon ];
130  }
131  return self;
132}
133
134@end
135